Added DB Access + Error page
This commit is contained in:
parent
3efba81ebc
commit
ffdc17efd5
@ -37,10 +37,23 @@ return array(
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
'db' => array(
|
||||||
|
'connectionString' => 'mysql:host=localhost;dbname=db451718',
|
||||||
|
'username' => 'root',
|
||||||
|
'password' => '',
|
||||||
|
'enableProfiling' => true,
|
||||||
|
'enableParamLogging' => true,
|
||||||
|
'charset' => 'utf8',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
'params' => array(
|
'params' => array(
|
||||||
// php configuration
|
// php configuration
|
||||||
'php.defaultCharset' => 'utf-8',
|
'php.defaultCharset' => 'utf-8',
|
||||||
'php.timezone' => 'UTC',
|
'php.timezone' => 'UTC',
|
||||||
|
|
||||||
|
'yii.handleErrors' => true,
|
||||||
|
'yii.debug' => true,
|
||||||
|
'yii.traceLevel' => 3,
|
||||||
)
|
)
|
||||||
);
|
);
|
33
app/config/env/dev.php
vendored
33
app/config/env/dev.php
vendored
@ -1,33 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Antonio Ramirez <amigo.cobos@gmail.com>
|
|
||||||
* @link http://www.ramirezcobos.com/
|
|
||||||
* @link http://www.2amigos.us/
|
|
||||||
* @copyright 2013 2amigOS! Consultation Group LLC
|
|
||||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
|
|
||||||
*/
|
|
||||||
return array(
|
|
||||||
'modules' => array(
|
|
||||||
'gii' => array(
|
|
||||||
'class' => 'system.gii.GiiModule',
|
|
||||||
'password' => 'yii',
|
|
||||||
'ipFilters' => array('127.0.0.1','::1'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
'components' => array(
|
|
||||||
'db' => array(
|
|
||||||
'connectionString' => 'mysql:host=localhost;dbname=db451718',
|
|
||||||
'username' => 'root',
|
|
||||||
'password' => '',
|
|
||||||
'enableProfiling' => true,
|
|
||||||
'enableParamLogging' => true,
|
|
||||||
'charset' => 'utf8',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
'params' => array(
|
|
||||||
'yii.handleErrors' => true,
|
|
||||||
'yii.debug' => true,
|
|
||||||
'yii.traceLevel' => 3,
|
|
||||||
)
|
|
||||||
);
|
|
26
app/config/env/prod.php
vendored
26
app/config/env/prod.php
vendored
@ -1,26 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Antonio Ramirez <amigo.cobos@gmail.com>
|
|
||||||
* @link http://www.ramirezcobos.com/
|
|
||||||
* @link http://www.2amigos.us/
|
|
||||||
* @copyright 2013 2amigOS! Consultation Group LLC
|
|
||||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
|
|
||||||
*/
|
|
||||||
return array(
|
|
||||||
'components' => array(
|
|
||||||
'db' => array(
|
|
||||||
'connectionString' => 'mysql:host=rdbms.strato.de;dbname=DB451718',
|
|
||||||
'username' => 'U451718',
|
|
||||||
'password' => 'Datenbank',
|
|
||||||
'enableProfiling' => YII_DEBUG,
|
|
||||||
'enableParamLogging' => YII_DEBUG,
|
|
||||||
'charset' => 'utf8',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
'params' => array(
|
|
||||||
'yii.debug' => false,
|
|
||||||
'yii.traceLevel' => 0,
|
|
||||||
'yii.handleErrors' => APP_CONFIG_NAME !== 'test',
|
|
||||||
)
|
|
||||||
);
|
|
7
app/config/env/stage.php
vendored
7
app/config/env/stage.php
vendored
@ -1,7 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* stage.php
|
|
||||||
*/
|
|
||||||
|
|
||||||
return array(
|
|
||||||
);
|
|
@ -91,16 +91,6 @@
|
|||||||
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.9.1.min.js"><\/script>')</script>
|
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.9.1.min.js"><\/script>')</script>
|
||||||
<script src="js/libs/bootstrap.min.js"></script>
|
<script src="js/libs/bootstrap.min.js"></script>
|
||||||
<script src="js/plugins.js"></script>
|
<script src="js/plugins.js"></script>
|
||||||
<script src="js/main.js"></script><script>
|
<script src="js/main.js"></script>
|
||||||
var _gaq = [
|
|
||||||
['_setAccount', 'UA-XXXXX-X'],
|
|
||||||
['_trackPageview']
|
|
||||||
];
|
|
||||||
(function (d, t) {
|
|
||||||
var g = d.createElement(t), s = d.getElementsByTagName(t)[0];
|
|
||||||
g.src = ('https:' == location.protocol ? '//ssl' : '//www') + '.google-analytics.com/ga.js';
|
|
||||||
s.parentNode.insertBefore(g, s)
|
|
||||||
}(document, 'script'));
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
12
app/views/site/error.php
Normal file
12
app/views/site/error.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
$this->pageTitle=Yii::app()->name . ' - Error';
|
||||||
|
$this->breadcrumbs=array(
|
||||||
|
'Error',
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h2>Error <?php echo $code; ?></h2>
|
||||||
|
|
||||||
|
<div class="error">
|
||||||
|
<?php echo CHtml::encode($message); ?>
|
||||||
|
</div>
|
@ -16,9 +16,27 @@
|
|||||||
<div class="span4">
|
<div class="span4">
|
||||||
<h2>Heading</h2>
|
<h2>Heading</h2>
|
||||||
|
|
||||||
<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris
|
<p>
|
||||||
condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis
|
|
||||||
euismod. Donec sed odio dui. </p>
|
<?php
|
||||||
|
$connection = Yii::app()->db;
|
||||||
|
|
||||||
|
$command=$connection->createCommand("SELECT * FROM programme");
|
||||||
|
$command->execute(); // a non-query SQL statement execution
|
||||||
|
// or execute an SQL query and fetch the result set
|
||||||
|
$reader=$command->query();
|
||||||
|
|
||||||
|
// each $row is an array representing a row of data
|
||||||
|
$dbgtxt = "ello";
|
||||||
|
foreach($reader as $row)
|
||||||
|
{
|
||||||
|
$dbgtxt = $dbgtxt . print_r($row, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo TbHtml::textArea('dbgtxt', $dbgtxt, array('rows' => 5));
|
||||||
|
?>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
|
||||||
<p><a class="btn" href="#">View details »</a></p>
|
<p><a class="btn" href="#">View details »</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
BIN
demos/blog/css/bg.gif
Normal file
BIN
demos/blog/css/bg.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 243 B |
166
demos/blog/css/form.css
Normal file
166
demos/blog/css/form.css
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
/**
|
||||||
|
* CSS styles for forms generated by yiic.
|
||||||
|
*
|
||||||
|
* The styles can be applied to the following form structure:
|
||||||
|
*
|
||||||
|
* <div class="form">
|
||||||
|
* <div class="row">
|
||||||
|
* <label for="inputid">xyz</label>
|
||||||
|
* <input name="inputid" id="inputid" type="text" />
|
||||||
|
* <p class="hint">hint text</p>
|
||||||
|
* </div>
|
||||||
|
* <div class="row">
|
||||||
|
* <label for="inputid">xyz</label>
|
||||||
|
* <input name="inputid" id="inputid" type="text" />
|
||||||
|
* <p class="hint">hint text</p>
|
||||||
|
* </div>
|
||||||
|
* <div class="row buttons">
|
||||||
|
* <label for="inputid">xyz</label>
|
||||||
|
* <input name="inputid" id="inputid" type="text" />
|
||||||
|
* <p class="hint">hint text</p>
|
||||||
|
* </div>
|
||||||
|
* </div>
|
||||||
|
*
|
||||||
|
* The above code will render the labels and input fields in separate lines.
|
||||||
|
* In order to render them in the same line, please use the "wide" form as follows,
|
||||||
|
*
|
||||||
|
* <div class="wide form">
|
||||||
|
* ......
|
||||||
|
* </div>
|
||||||
|
*
|
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||||
|
* @link http://www.yiiframework.com/
|
||||||
|
* @copyright 2008-2010 Yii Software LLC
|
||||||
|
* @license http://www.yiiframework.com/license/
|
||||||
|
*/
|
||||||
|
|
||||||
|
div.form
|
||||||
|
{
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.form input,
|
||||||
|
div.form textarea,
|
||||||
|
div.form select
|
||||||
|
{
|
||||||
|
margin: 0.2em 0 0.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.form fieldset
|
||||||
|
{
|
||||||
|
border: 1px solid #DDD;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
-moz-border-radius:7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.form label
|
||||||
|
{
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 0.9em;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.form .row
|
||||||
|
{
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.form .hint
|
||||||
|
{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.form .note
|
||||||
|
{
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.form span.required
|
||||||
|
{
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.form div.error label,
|
||||||
|
div.form label.error,
|
||||||
|
div.form span.error
|
||||||
|
{
|
||||||
|
color: #C00;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.form div.error input,
|
||||||
|
div.form div.error textarea,
|
||||||
|
div.form div.error select,
|
||||||
|
div.form input.error,
|
||||||
|
div.form textarea.error,
|
||||||
|
div.form select.error
|
||||||
|
{
|
||||||
|
background: #FEE;
|
||||||
|
border-color: #C00;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.form div.success input,
|
||||||
|
div.form div.success textarea,
|
||||||
|
div.form div.success select,
|
||||||
|
div.form input.success,
|
||||||
|
div.form textarea.success,
|
||||||
|
div.form select.success
|
||||||
|
{
|
||||||
|
background: #E6EFC2;
|
||||||
|
border-color: #C6D880;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
div.form .errorSummary
|
||||||
|
{
|
||||||
|
border: 2px solid #C00;
|
||||||
|
padding: 7px 7px 12px 7px;
|
||||||
|
margin: 0 0 20px 0;
|
||||||
|
background: #FEE;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.form .errorMessage
|
||||||
|
{
|
||||||
|
color: red;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.form .errorSummary p
|
||||||
|
{
|
||||||
|
margin: 0;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.form .errorSummary ul
|
||||||
|
{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 0 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.wide form label
|
||||||
|
{
|
||||||
|
float: left;
|
||||||
|
margin-right: 10px;
|
||||||
|
position: relative;
|
||||||
|
text-align: right;
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.wide form .row
|
||||||
|
{
|
||||||
|
clear: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.wide form .buttons
|
||||||
|
{
|
||||||
|
clear: left;
|
||||||
|
padding-left: 110px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.wide form .errorMessage
|
||||||
|
{
|
||||||
|
margin: 0 0 0 110px;
|
||||||
|
}
|
35
demos/blog/css/ie.css
Normal file
35
demos/blog/css/ie.css
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Blueprint CSS Framework 0.9
|
||||||
|
http://blueprintcss.org
|
||||||
|
|
||||||
|
* Copyright (c) 2007-Present. See LICENSE for more info.
|
||||||
|
* See README for instructions on how to use Blueprint.
|
||||||
|
* For credits and origins, see AUTHORS.
|
||||||
|
* This is a compressed file. See the sources in the 'src' directory.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* ie.css */
|
||||||
|
body {text-align:center;}
|
||||||
|
.container {text-align:left;}
|
||||||
|
* html .column, * html div.span-1, * html div.span-2, * html div.span-3, * html div.span-4, * html div.span-5, * html div.span-6, * html div.span-7, * html div.span-8, * html div.span-9, * html div.span-10, * html div.span-11, * html div.span-12, * html div.span-13, * html div.span-14, * html div.span-15, * html div.span-16, * html div.span-17, * html div.span-18, * html div.span-19, * html div.span-20, * html div.span-21, * html div.span-22, * html div.span-23, * html div.span-24 {display:inline;overflow-x:hidden;}
|
||||||
|
* html legend {margin:0px -8px 16px 0;padding:0;}
|
||||||
|
sup {vertical-align:text-top;}
|
||||||
|
sub {vertical-align:text-bottom;}
|
||||||
|
html>body p code {*white-space:normal;}
|
||||||
|
hr {margin:-8px auto 11px;}
|
||||||
|
img {-ms-interpolation-mode:bicubic;}
|
||||||
|
.clearfix, .container {display:inline-block;}
|
||||||
|
* html .clearfix, * html .container {height:1%;}
|
||||||
|
fieldset {padding-top:0;}
|
||||||
|
textarea {overflow:auto;}
|
||||||
|
input.text, input.title, textarea {background-color:#fff;border:1px solid #bbb;}
|
||||||
|
input.text:focus, input.title:focus {border-color:#666;}
|
||||||
|
input.text, input.title, textarea, select {margin:0.5em 0;}
|
||||||
|
input.checkbox, input.radio {position:relative;top:.25em;}
|
||||||
|
form.inline div, form.inline p {vertical-align:middle;}
|
||||||
|
form.inline label {position:relative;top:-0.25em;}
|
||||||
|
form.inline input.checkbox, form.inline input.radio, form.inline input.button, form.inline button {margin:0.5em 0;}
|
||||||
|
button, input.button {position:relative;top:0.25em;}
|
267
demos/blog/css/main.css
Normal file
267
demos/blog/css/main.css
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
body
|
||||||
|
{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
color: #555;
|
||||||
|
font: normal 10pt Arial,Helvetica,sans-serif;
|
||||||
|
background: #EFEFEF;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page
|
||||||
|
{
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
background: white;
|
||||||
|
border: 1px solid #C9E0ED;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header
|
||||||
|
{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border-top: 3px solid #C9E0ED;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content
|
||||||
|
{
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar
|
||||||
|
{
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer
|
||||||
|
{
|
||||||
|
padding: 10px;
|
||||||
|
margin: 10px 20px;
|
||||||
|
font-size: 0.8em;
|
||||||
|
text-align: center;
|
||||||
|
border-top: 1px solid #C9E0ED;
|
||||||
|
}
|
||||||
|
|
||||||
|
#logo
|
||||||
|
{
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-size: 200%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mainmenu
|
||||||
|
{
|
||||||
|
background:white url(bg.gif) repeat-x left top;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mainmenu ul
|
||||||
|
{
|
||||||
|
padding:6px 20px 5px 20px;
|
||||||
|
margin:0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mainmenu ul li
|
||||||
|
{
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mainmenu ul li a
|
||||||
|
{
|
||||||
|
color:#ffffff;
|
||||||
|
background-color:transparent;
|
||||||
|
font-size:12px;
|
||||||
|
font-weight:bold;
|
||||||
|
text-decoration:none;
|
||||||
|
padding:5px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mainmenu ul li a:hover, #mainmenu ul li.active a
|
||||||
|
{
|
||||||
|
color: #6399cd;
|
||||||
|
background-color:#EFF4FA;
|
||||||
|
text-decoration:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.flash-error, div.flash-notice, div.flash-success
|
||||||
|
{
|
||||||
|
padding:.8em;
|
||||||
|
margin-bottom:1em;
|
||||||
|
border:2px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.flash-error
|
||||||
|
{
|
||||||
|
background:#FBE3E4;
|
||||||
|
color:#8a1f11;
|
||||||
|
border-color:#FBC2C4;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.flash-notice
|
||||||
|
{
|
||||||
|
background:#FFF6BF;
|
||||||
|
color:#514721;
|
||||||
|
border-color:#FFD324;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.flash-success
|
||||||
|
{
|
||||||
|
background:#E6EFC2;
|
||||||
|
color:#264409;
|
||||||
|
border-color:#C6D880;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.flash-error a
|
||||||
|
{
|
||||||
|
color:#8a1f11;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.flash-notice a
|
||||||
|
{
|
||||||
|
color:#514721;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.flash-success a
|
||||||
|
{
|
||||||
|
color:#264409;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.form .rememberMe label
|
||||||
|
{
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.view
|
||||||
|
{
|
||||||
|
padding: 10px;
|
||||||
|
margin: 10px 0;
|
||||||
|
border: 1px solid #C9E0ED;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.breadcrumbs
|
||||||
|
{
|
||||||
|
font-size: 0.9em;
|
||||||
|
padding: 5px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.breadcrumbs span
|
||||||
|
{
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.portlet
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.portlet-decoration
|
||||||
|
{
|
||||||
|
padding: 3px 8px;
|
||||||
|
background: #B7D6E7;
|
||||||
|
border-left: 5px solid #6FACCF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.portlet-title
|
||||||
|
{
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
color: #298dcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.portlet-content
|
||||||
|
{
|
||||||
|
font-size:0.9em;
|
||||||
|
margin: 0;
|
||||||
|
padding: 5px 8px;
|
||||||
|
margin-bottom:15px;
|
||||||
|
background:#EFFDFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.portlet-content ul
|
||||||
|
{
|
||||||
|
list-style-image:none;
|
||||||
|
list-style-position:outside;
|
||||||
|
list-style-type:none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.portlet-content li
|
||||||
|
{
|
||||||
|
padding: 2px 0 4px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post
|
||||||
|
{
|
||||||
|
margin: 0 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post .title
|
||||||
|
{
|
||||||
|
font-size: 1.5em;
|
||||||
|
border-bottom: 1px solid #C9E0ED;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post .title a
|
||||||
|
{
|
||||||
|
color: #555;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post .author
|
||||||
|
{
|
||||||
|
color: #888;
|
||||||
|
margin: 0 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post .nav
|
||||||
|
{
|
||||||
|
-moz-border-radius:7px;
|
||||||
|
padding: 5px;
|
||||||
|
background: #EFFDFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment
|
||||||
|
{
|
||||||
|
-moz-border-radius:7px;
|
||||||
|
padding: 10px;
|
||||||
|
background: #F5F5F5;
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment .content
|
||||||
|
{
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment .author
|
||||||
|
{
|
||||||
|
margin: 5px 0;
|
||||||
|
padding: 0 0 3px;
|
||||||
|
border-bottom: 1px solid #DDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment .time
|
||||||
|
{
|
||||||
|
color: #888;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment a.cid
|
||||||
|
{
|
||||||
|
color:#CCC;
|
||||||
|
float:right;
|
||||||
|
font-size:1.5em;
|
||||||
|
font-weight:bold;
|
||||||
|
padding:0 5px 5px 5px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment a.cid:hover
|
||||||
|
{
|
||||||
|
color:#555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment .pending
|
||||||
|
{
|
||||||
|
color:red;
|
||||||
|
}
|
29
demos/blog/css/print.css
Normal file
29
demos/blog/css/print.css
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Blueprint CSS Framework 0.9
|
||||||
|
http://blueprintcss.org
|
||||||
|
|
||||||
|
* Copyright (c) 2007-Present. See LICENSE for more info.
|
||||||
|
* See README for instructions on how to use Blueprint.
|
||||||
|
* For credits and origins, see AUTHORS.
|
||||||
|
* This is a compressed file. See the sources in the 'src' directory.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* print.css */
|
||||||
|
body {line-height:1.5;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;color:#000;background:none;font-size:10pt;}
|
||||||
|
.container {background:none;}
|
||||||
|
hr {background:#ccc;color:#ccc;width:100%;height:2px;margin:2em 0;padding:0;border:none;}
|
||||||
|
hr.space {background:#fff;color:#fff;visibility:hidden;}
|
||||||
|
h1, h2, h3, h4, h5, h6 {font-family:"Helvetica Neue", Arial, "Lucida Grande", sans-serif;}
|
||||||
|
code {font:.9em "Courier New", Monaco, Courier, monospace;}
|
||||||
|
a img {border:none;}
|
||||||
|
p img.top {margin-top:0;}
|
||||||
|
blockquote {margin:1.5em;padding:1em;font-style:italic;font-size:.9em;}
|
||||||
|
.small {font-size:.9em;}
|
||||||
|
.large {font-size:1.1em;}
|
||||||
|
.quiet {color:#999;}
|
||||||
|
.hide {display:none;}
|
||||||
|
a:link, a:visited {background:transparent;font-weight:700;text-decoration:underline;}
|
||||||
|
a:link:after, a:visited:after {content:" (" attr(href) ")";font-size:90%;}
|
235
demos/blog/css/screen.css
Normal file
235
demos/blog/css/screen.css
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
/* -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Blueprint CSS Framework 0.9
|
||||||
|
http://blueprintcss.org
|
||||||
|
|
||||||
|
* Copyright (c) 2007-Present. See LICENSE for more info.
|
||||||
|
* See README for instructions on how to use Blueprint.
|
||||||
|
* For credits and origins, see AUTHORS.
|
||||||
|
* This is a compressed file. See the sources in the 'src' directory.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* reset.css */
|
||||||
|
html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, img, q, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td {margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;}
|
||||||
|
body {line-height:1.5;}
|
||||||
|
table {border-collapse:separate;border-spacing:0;}
|
||||||
|
caption, th, td {text-align:left;font-weight:normal;}
|
||||||
|
table, td, th {vertical-align:middle;}
|
||||||
|
blockquote:before, blockquote:after, q:before, q:after {content:"";}
|
||||||
|
blockquote, q {quotes:"" "";}
|
||||||
|
a img {border:none;}
|
||||||
|
|
||||||
|
/* typography.css */
|
||||||
|
html {font-size:100.01%;}
|
||||||
|
body {font-size:75%;color:#222;background:#fff;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;}
|
||||||
|
h1, h2, h3, h4, h5, h6 {font-weight:normal;color:#111;}
|
||||||
|
h1 {font-size:2em;line-height:1;margin-bottom:0.5em;}
|
||||||
|
h2 {font-size:1.6em;margin-bottom:0.75em;}
|
||||||
|
h3 {font-size:1.4em;line-height:1;margin-bottom:1em;}
|
||||||
|
h4 {font-size:1.2em;line-height:1.25;margin-bottom:1.25em;}
|
||||||
|
h5 {font-size:1em;font-weight:bold;margin-bottom:1.5em;}
|
||||||
|
h6 {font-size:1em;font-weight:bold;}
|
||||||
|
h1 img, h2 img, h3 img, h4 img, h5 img, h6 img {margin:0;}
|
||||||
|
p {margin:0 0 1.5em;}
|
||||||
|
p img.left {float:left;margin:1.5em 1.5em 1.5em 0;padding:0;}
|
||||||
|
p img.right {float:right;margin:1.5em 0 1.5em 1.5em;}
|
||||||
|
a:focus, a:hover {color:#000;}
|
||||||
|
a {color:#009;text-decoration:underline;}
|
||||||
|
blockquote {margin:1.5em;color:#666;font-style:italic;}
|
||||||
|
strong {font-weight:bold;}
|
||||||
|
em, dfn {font-style:italic;}
|
||||||
|
dfn {font-weight:bold;}
|
||||||
|
sup, sub {line-height:0;}
|
||||||
|
abbr, acronym {border-bottom:1px dotted #666;}
|
||||||
|
address {margin:0 0 1.5em;font-style:italic;}
|
||||||
|
del {color:#666;}
|
||||||
|
pre {margin:1.5em 0;white-space:pre;}
|
||||||
|
pre, code, tt {font:1em 'andale mono', 'lucida console', monospace;line-height:1.5;}
|
||||||
|
li ul, li ol {margin:0;}
|
||||||
|
ul, ol {margin:0 1.5em 1.5em 0;padding-left:3.333em;}
|
||||||
|
ul {list-style-type:disc;}
|
||||||
|
ol {list-style-type:decimal;}
|
||||||
|
dl {margin:0 0 1.5em 0;}
|
||||||
|
dl dt {font-weight:bold;}
|
||||||
|
dd {margin-left:1.5em;}
|
||||||
|
table {margin-bottom:1.4em;width:100%;}
|
||||||
|
th {font-weight:bold;}
|
||||||
|
thead th {background:#c3d9ff;}
|
||||||
|
th, td, caption {padding:4px 10px 4px 5px;}
|
||||||
|
tfoot {font-style:italic;}
|
||||||
|
caption {background:#eee;}
|
||||||
|
.small {font-size:.8em;margin-bottom:1.875em;line-height:1.875em;}
|
||||||
|
.large {font-size:1.2em;line-height:2.5em;margin-bottom:1.25em;}
|
||||||
|
.hide {display:none;}
|
||||||
|
.quiet {color:#666;}
|
||||||
|
.loud {color:#000;}
|
||||||
|
.highlight {background:#ff0;}
|
||||||
|
.added {background:#060;color:#fff;}
|
||||||
|
.removed {background:#900;color:#fff;}
|
||||||
|
.first {margin-left:0;padding-left:0;}
|
||||||
|
.last {margin-right:0;padding-right:0;}
|
||||||
|
.top {margin-top:0;padding-top:0;}
|
||||||
|
.bottom {margin-bottom:0;padding-bottom:0;}
|
||||||
|
|
||||||
|
/* grid.css */
|
||||||
|
.container {width:950px;margin:0 auto;}
|
||||||
|
.showgrid {background:url(src/grid.png);}
|
||||||
|
.column, div.span-1, div.span-2, div.span-3, div.span-4, div.span-5, div.span-6, div.span-7, div.span-8, div.span-9, div.span-10, div.span-11, div.span-12, div.span-13, div.span-14, div.span-15, div.span-16, div.span-17, div.span-18, div.span-19, div.span-20, div.span-21, div.span-22, div.span-23, div.span-24 {float:left;margin-right:10px;}
|
||||||
|
.last, div.last {margin-right:0;}
|
||||||
|
.span-1 {width:30px;}
|
||||||
|
.span-2 {width:70px;}
|
||||||
|
.span-3 {width:110px;}
|
||||||
|
.span-4 {width:150px;}
|
||||||
|
.span-5 {width:190px;}
|
||||||
|
.span-6 {width:230px;}
|
||||||
|
.span-7 {width:270px;}
|
||||||
|
.span-8 {width:310px;}
|
||||||
|
.span-9 {width:350px;}
|
||||||
|
.span-10 {width:390px;}
|
||||||
|
.span-11 {width:430px;}
|
||||||
|
.span-12 {width:470px;}
|
||||||
|
.span-13 {width:510px;}
|
||||||
|
.span-14 {width:550px;}
|
||||||
|
.span-15 {width:590px;}
|
||||||
|
.span-16 {width:630px;}
|
||||||
|
.span-17 {width:670px;}
|
||||||
|
.span-18 {width:710px;}
|
||||||
|
.span-19 {width:750px;}
|
||||||
|
.span-20 {width:790px;}
|
||||||
|
.span-21 {width:830px;}
|
||||||
|
.span-22 {width:870px;}
|
||||||
|
.span-23 {width:910px;}
|
||||||
|
.span-24, div.span-24 {width:950px;margin-right:0;}
|
||||||
|
input.span-1, textarea.span-1, input.span-2, textarea.span-2, input.span-3, textarea.span-3, input.span-4, textarea.span-4, input.span-5, textarea.span-5, input.span-6, textarea.span-6, input.span-7, textarea.span-7, input.span-8, textarea.span-8, input.span-9, textarea.span-9, input.span-10, textarea.span-10, input.span-11, textarea.span-11, input.span-12, textarea.span-12, input.span-13, textarea.span-13, input.span-14, textarea.span-14, input.span-15, textarea.span-15, input.span-16, textarea.span-16, input.span-17, textarea.span-17, input.span-18, textarea.span-18, input.span-19, textarea.span-19, input.span-20, textarea.span-20, input.span-21, textarea.span-21, input.span-22, textarea.span-22, input.span-23, textarea.span-23, input.span-24, textarea.span-24 {border-left-width:1px!important;border-right-width:1px!important;padding-left:5px!important;padding-right:5px!important;}
|
||||||
|
input.span-1, textarea.span-1 {width:18px!important;}
|
||||||
|
input.span-2, textarea.span-2 {width:58px!important;}
|
||||||
|
input.span-3, textarea.span-3 {width:98px!important;}
|
||||||
|
input.span-4, textarea.span-4 {width:138px!important;}
|
||||||
|
input.span-5, textarea.span-5 {width:178px!important;}
|
||||||
|
input.span-6, textarea.span-6 {width:218px!important;}
|
||||||
|
input.span-7, textarea.span-7 {width:258px!important;}
|
||||||
|
input.span-8, textarea.span-8 {width:298px!important;}
|
||||||
|
input.span-9, textarea.span-9 {width:338px!important;}
|
||||||
|
input.span-10, textarea.span-10 {width:378px!important;}
|
||||||
|
input.span-11, textarea.span-11 {width:418px!important;}
|
||||||
|
input.span-12, textarea.span-12 {width:458px!important;}
|
||||||
|
input.span-13, textarea.span-13 {width:498px!important;}
|
||||||
|
input.span-14, textarea.span-14 {width:538px!important;}
|
||||||
|
input.span-15, textarea.span-15 {width:578px!important;}
|
||||||
|
input.span-16, textarea.span-16 {width:618px!important;}
|
||||||
|
input.span-17, textarea.span-17 {width:658px!important;}
|
||||||
|
input.span-18, textarea.span-18 {width:698px!important;}
|
||||||
|
input.span-19, textarea.span-19 {width:738px!important;}
|
||||||
|
input.span-20, textarea.span-20 {width:778px!important;}
|
||||||
|
input.span-21, textarea.span-21 {width:818px!important;}
|
||||||
|
input.span-22, textarea.span-22 {width:858px!important;}
|
||||||
|
input.span-23, textarea.span-23 {width:898px!important;}
|
||||||
|
input.span-24, textarea.span-24 {width:938px!important;}
|
||||||
|
.append-1 {padding-right:40px;}
|
||||||
|
.append-2 {padding-right:80px;}
|
||||||
|
.append-3 {padding-right:120px;}
|
||||||
|
.append-4 {padding-right:160px;}
|
||||||
|
.append-5 {padding-right:200px;}
|
||||||
|
.append-6 {padding-right:240px;}
|
||||||
|
.append-7 {padding-right:280px;}
|
||||||
|
.append-8 {padding-right:320px;}
|
||||||
|
.append-9 {padding-right:360px;}
|
||||||
|
.append-10 {padding-right:400px;}
|
||||||
|
.append-11 {padding-right:440px;}
|
||||||
|
.append-12 {padding-right:480px;}
|
||||||
|
.append-13 {padding-right:520px;}
|
||||||
|
.append-14 {padding-right:560px;}
|
||||||
|
.append-15 {padding-right:600px;}
|
||||||
|
.append-16 {padding-right:640px;}
|
||||||
|
.append-17 {padding-right:680px;}
|
||||||
|
.append-18 {padding-right:720px;}
|
||||||
|
.append-19 {padding-right:760px;}
|
||||||
|
.append-20 {padding-right:800px;}
|
||||||
|
.append-21 {padding-right:840px;}
|
||||||
|
.append-22 {padding-right:880px;}
|
||||||
|
.append-23 {padding-right:920px;}
|
||||||
|
.prepend-1 {padding-left:40px;}
|
||||||
|
.prepend-2 {padding-left:80px;}
|
||||||
|
.prepend-3 {padding-left:120px;}
|
||||||
|
.prepend-4 {padding-left:160px;}
|
||||||
|
.prepend-5 {padding-left:200px;}
|
||||||
|
.prepend-6 {padding-left:240px;}
|
||||||
|
.prepend-7 {padding-left:280px;}
|
||||||
|
.prepend-8 {padding-left:320px;}
|
||||||
|
.prepend-9 {padding-left:360px;}
|
||||||
|
.prepend-10 {padding-left:400px;}
|
||||||
|
.prepend-11 {padding-left:440px;}
|
||||||
|
.prepend-12 {padding-left:480px;}
|
||||||
|
.prepend-13 {padding-left:520px;}
|
||||||
|
.prepend-14 {padding-left:560px;}
|
||||||
|
.prepend-15 {padding-left:600px;}
|
||||||
|
.prepend-16 {padding-left:640px;}
|
||||||
|
.prepend-17 {padding-left:680px;}
|
||||||
|
.prepend-18 {padding-left:720px;}
|
||||||
|
.prepend-19 {padding-left:760px;}
|
||||||
|
.prepend-20 {padding-left:800px;}
|
||||||
|
.prepend-21 {padding-left:840px;}
|
||||||
|
.prepend-22 {padding-left:880px;}
|
||||||
|
.prepend-23 {padding-left:920px;}
|
||||||
|
div.border {padding-right:4px;margin-right:5px;border-right:1px solid #eee;}
|
||||||
|
div.colborder {padding-right:24px;margin-right:25px;border-right:1px solid #eee;}
|
||||||
|
.pull-1 {margin-left:-40px;}
|
||||||
|
.pull-2 {margin-left:-80px;}
|
||||||
|
.pull-3 {margin-left:-120px;}
|
||||||
|
.pull-4 {margin-left:-160px;}
|
||||||
|
.pull-5 {margin-left:-200px;}
|
||||||
|
.pull-6 {margin-left:-240px;}
|
||||||
|
.pull-7 {margin-left:-280px;}
|
||||||
|
.pull-8 {margin-left:-320px;}
|
||||||
|
.pull-9 {margin-left:-360px;}
|
||||||
|
.pull-10 {margin-left:-400px;}
|
||||||
|
.pull-11 {margin-left:-440px;}
|
||||||
|
.pull-12 {margin-left:-480px;}
|
||||||
|
.pull-13 {margin-left:-520px;}
|
||||||
|
.pull-14 {margin-left:-560px;}
|
||||||
|
.pull-15 {margin-left:-600px;}
|
||||||
|
.pull-16 {margin-left:-640px;}
|
||||||
|
.pull-17 {margin-left:-680px;}
|
||||||
|
.pull-18 {margin-left:-720px;}
|
||||||
|
.pull-19 {margin-left:-760px;}
|
||||||
|
.pull-20 {margin-left:-800px;}
|
||||||
|
.pull-21 {margin-left:-840px;}
|
||||||
|
.pull-22 {margin-left:-880px;}
|
||||||
|
.pull-23 {margin-left:-920px;}
|
||||||
|
.pull-24 {margin-left:-960px;}
|
||||||
|
.pull-1, .pull-2, .pull-3, .pull-4, .pull-5, .pull-6, .pull-7, .pull-8, .pull-9, .pull-10, .pull-11, .pull-12, .pull-13, .pull-14, .pull-15, .pull-16, .pull-17, .pull-18, .pull-19, .pull-20, .pull-21, .pull-22, .pull-23, .pull-24 {float:left;position:relative;}
|
||||||
|
.push-1 {margin:0 -40px 1.5em 40px;}
|
||||||
|
.push-2 {margin:0 -80px 1.5em 80px;}
|
||||||
|
.push-3 {margin:0 -120px 1.5em 120px;}
|
||||||
|
.push-4 {margin:0 -160px 1.5em 160px;}
|
||||||
|
.push-5 {margin:0 -200px 1.5em 200px;}
|
||||||
|
.push-6 {margin:0 -240px 1.5em 240px;}
|
||||||
|
.push-7 {margin:0 -280px 1.5em 280px;}
|
||||||
|
.push-8 {margin:0 -320px 1.5em 320px;}
|
||||||
|
.push-9 {margin:0 -360px 1.5em 360px;}
|
||||||
|
.push-10 {margin:0 -400px 1.5em 400px;}
|
||||||
|
.push-11 {margin:0 -440px 1.5em 440px;}
|
||||||
|
.push-12 {margin:0 -480px 1.5em 480px;}
|
||||||
|
.push-13 {margin:0 -520px 1.5em 520px;}
|
||||||
|
.push-14 {margin:0 -560px 1.5em 560px;}
|
||||||
|
.push-15 {margin:0 -600px 1.5em 600px;}
|
||||||
|
.push-16 {margin:0 -640px 1.5em 640px;}
|
||||||
|
.push-17 {margin:0 -680px 1.5em 680px;}
|
||||||
|
.push-18 {margin:0 -720px 1.5em 720px;}
|
||||||
|
.push-19 {margin:0 -760px 1.5em 760px;}
|
||||||
|
.push-20 {margin:0 -800px 1.5em 800px;}
|
||||||
|
.push-21 {margin:0 -840px 1.5em 840px;}
|
||||||
|
.push-22 {margin:0 -880px 1.5em 880px;}
|
||||||
|
.push-23 {margin:0 -920px 1.5em 920px;}
|
||||||
|
.push-24 {margin:0 -960px 1.5em 960px;}
|
||||||
|
.push-1, .push-2, .push-3, .push-4, .push-5, .push-6, .push-7, .push-8, .push-9, .push-10, .push-11, .push-12, .push-13, .push-14, .push-15, .push-16, .push-17, .push-18, .push-19, .push-20, .push-21, .push-22, .push-23, .push-24 {float:right;position:relative;}
|
||||||
|
.prepend-top {margin-top:1.5em;}
|
||||||
|
.append-bottom {margin-bottom:1.5em;}
|
||||||
|
.box {padding:1.5em;margin-bottom:1.5em;background:#E5ECF9;}
|
||||||
|
hr {background:#ddd;color:#ddd;clear:both;float:none;width:100%;height:.1em;margin:0 0 1.45em;border:none;}
|
||||||
|
hr.space {background:#fff;color:#fff;visibility:hidden;}
|
||||||
|
.clearfix:after, .container:after {content:"\0020";display:block;height:0;clear:both;visibility:hidden;overflow:hidden;}
|
||||||
|
.clearfix, .container {display:block;}
|
||||||
|
.clear {clear:both;}
|
15
demos/blog/index-test.php
Normal file
15
demos/blog/index-test.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This is the bootstrap file for test application.
|
||||||
|
* This file should be removed when the application is deployed for production.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// change the following paths if necessary
|
||||||
|
$yii=dirname(__FILE__).'/../../framework/yii.php';
|
||||||
|
$config=dirname(__FILE__).'/protected/config/test.php';
|
||||||
|
|
||||||
|
// remove the following line when in production mode
|
||||||
|
// defined('YII_DEBUG') or define('YII_DEBUG',true);
|
||||||
|
|
||||||
|
require_once($yii);
|
||||||
|
Yii::createWebApplication($config)->run();
|
11
demos/blog/index.php
Normal file
11
demos/blog/index.php
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// change the following paths if necessary
|
||||||
|
$yii=dirname(__FILE__).'/../../framework/yii.php';
|
||||||
|
$config=dirname(__FILE__).'/protected/config/main.php';
|
||||||
|
|
||||||
|
// remove the following line when in production mode
|
||||||
|
// defined('YII_DEBUG') or define('YII_DEBUG',true);
|
||||||
|
|
||||||
|
require_once($yii);
|
||||||
|
Yii::createWebApplication($config)->run();
|
1
demos/blog/protected/.htaccess
Normal file
1
demos/blog/protected/.htaccess
Normal file
@ -0,0 +1 @@
|
|||||||
|
deny from all
|
23
demos/blog/protected/components/Controller.php
Normal file
23
demos/blog/protected/components/Controller.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Controller is the customized base controller class.
|
||||||
|
* All controller classes for this application should extend from this base class.
|
||||||
|
*/
|
||||||
|
class Controller extends CController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string the default layout for the controller view. Defaults to 'column1',
|
||||||
|
* meaning using a single column layout. See 'protected/views/layouts/column1.php'.
|
||||||
|
*/
|
||||||
|
public $layout='column1';
|
||||||
|
/**
|
||||||
|
* @var array context menu items. This property will be assigned to {@link CMenu::items}.
|
||||||
|
*/
|
||||||
|
public $menu=array();
|
||||||
|
/**
|
||||||
|
* @var array the breadcrumbs of the current page. The value of this property will
|
||||||
|
* be assigned to {@link CBreadcrumbs::links}. Please refer to {@link CBreadcrumbs::links}
|
||||||
|
* for more details on how to specify this property.
|
||||||
|
*/
|
||||||
|
public $breadcrumbs=array();
|
||||||
|
}
|
19
demos/blog/protected/components/RecentComments.php
Normal file
19
demos/blog/protected/components/RecentComments.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
Yii::import('zii.widgets.CPortlet');
|
||||||
|
|
||||||
|
class RecentComments extends CPortlet
|
||||||
|
{
|
||||||
|
public $title='Recent Comments';
|
||||||
|
public $maxComments=10;
|
||||||
|
|
||||||
|
public function getRecentComments()
|
||||||
|
{
|
||||||
|
return Comment::model()->findRecentComments($this->maxComments);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderContent()
|
||||||
|
{
|
||||||
|
$this->render('recentComments');
|
||||||
|
}
|
||||||
|
}
|
23
demos/blog/protected/components/TagCloud.php
Normal file
23
demos/blog/protected/components/TagCloud.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
Yii::import('zii.widgets.CPortlet');
|
||||||
|
|
||||||
|
class TagCloud extends CPortlet
|
||||||
|
{
|
||||||
|
public $title='Tags';
|
||||||
|
public $maxTags=20;
|
||||||
|
|
||||||
|
protected function renderContent()
|
||||||
|
{
|
||||||
|
$tags=Tag::model()->findTagWeights($this->maxTags);
|
||||||
|
|
||||||
|
foreach($tags as $tag=>$weight)
|
||||||
|
{
|
||||||
|
$link=CHtml::link(CHtml::encode($tag), array('post/index','tag'=>$tag));
|
||||||
|
echo CHtml::tag('span', array(
|
||||||
|
'class'=>'tag',
|
||||||
|
'style'=>"font-size:{$weight}pt",
|
||||||
|
), $link)."\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
39
demos/blog/protected/components/UserIdentity.php
Normal file
39
demos/blog/protected/components/UserIdentity.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UserIdentity represents the data needed to identity a user.
|
||||||
|
* It contains the authentication method that checks if the provided
|
||||||
|
* data can identity the user.
|
||||||
|
*/
|
||||||
|
class UserIdentity extends CUserIdentity
|
||||||
|
{
|
||||||
|
private $_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticates a user.
|
||||||
|
* @return boolean whether authentication succeeds.
|
||||||
|
*/
|
||||||
|
public function authenticate()
|
||||||
|
{
|
||||||
|
$user=User::model()->find('LOWER(username)=?',array(strtolower($this->username)));
|
||||||
|
if($user===null)
|
||||||
|
$this->errorCode=self::ERROR_USERNAME_INVALID;
|
||||||
|
else if(!$user->validatePassword($this->password))
|
||||||
|
$this->errorCode=self::ERROR_PASSWORD_INVALID;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->_id=$user->id;
|
||||||
|
$this->username=$user->username;
|
||||||
|
$this->errorCode=self::ERROR_NONE;
|
||||||
|
}
|
||||||
|
return $this->errorCode==self::ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return integer the ID of the user record
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return $this->_id;
|
||||||
|
}
|
||||||
|
}
|
17
demos/blog/protected/components/UserMenu.php
Normal file
17
demos/blog/protected/components/UserMenu.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
Yii::import('zii.widgets.CPortlet');
|
||||||
|
|
||||||
|
class UserMenu extends CPortlet
|
||||||
|
{
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
$this->title=CHtml::encode(Yii::app()->user->name);
|
||||||
|
parent::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderContent()
|
||||||
|
{
|
||||||
|
$this->render('userMenu');
|
||||||
|
}
|
||||||
|
}
|
7
demos/blog/protected/components/views/recentComments.php
Normal file
7
demos/blog/protected/components/views/recentComments.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<ul>
|
||||||
|
<?php foreach($this->getRecentComments() as $comment): ?>
|
||||||
|
<li><?php echo $comment->authorLink; ?> on
|
||||||
|
<?php echo CHtml::link(CHtml::encode($comment->post->title), $comment->getUrl()); ?>
|
||||||
|
</li>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</ul>
|
6
demos/blog/protected/components/views/userMenu.php
Normal file
6
demos/blog/protected/components/views/userMenu.php
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<ul>
|
||||||
|
<li><?php echo CHtml::link('Create New Post',array('post/create')); ?></li>
|
||||||
|
<li><?php echo CHtml::link('Manage Posts',array('post/admin')); ?></li>
|
||||||
|
<li><?php echo CHtml::link('Approve Comments',array('comment/index')) . ' (' . Comment::model()->pendingCommentCount . ')'; ?></li>
|
||||||
|
<li><?php echo CHtml::link('Logout',array('site/logout')); ?></li>
|
||||||
|
</ul>
|
8
demos/blog/protected/config/console.php
Normal file
8
demos/blog/protected/config/console.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// This is the configuration for yiic console application.
|
||||||
|
// Any writable CConsoleApplication properties can be configured here.
|
||||||
|
return array(
|
||||||
|
'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
|
||||||
|
'name'=>'My Console Application',
|
||||||
|
);
|
76
demos/blog/protected/config/main.php
Normal file
76
demos/blog/protected/config/main.php
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// uncomment the following to define a path alias
|
||||||
|
// Yii::setPathOfAlias('local','path/to/local-folder');
|
||||||
|
|
||||||
|
// This is the main Web application configuration. Any writable
|
||||||
|
// CWebApplication properties can be configured here.
|
||||||
|
return array(
|
||||||
|
'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
|
||||||
|
'name'=>'Yii Blog Demo',
|
||||||
|
|
||||||
|
// preloading 'log' component
|
||||||
|
'preload'=>array('log'),
|
||||||
|
|
||||||
|
// autoloading model and component classes
|
||||||
|
'import'=>array(
|
||||||
|
'application.models.*',
|
||||||
|
'application.components.*',
|
||||||
|
),
|
||||||
|
|
||||||
|
'defaultController'=>'post',
|
||||||
|
|
||||||
|
// application components
|
||||||
|
'components'=>array(
|
||||||
|
'user'=>array(
|
||||||
|
// enable cookie-based authentication
|
||||||
|
'allowAutoLogin'=>true,
|
||||||
|
),
|
||||||
|
'db'=>array(
|
||||||
|
'connectionString' => 'sqlite:protected/data/blog.db',
|
||||||
|
'tablePrefix' => 'tbl_',
|
||||||
|
),
|
||||||
|
// uncomment the following to use a MySQL database
|
||||||
|
/*
|
||||||
|
'db'=>array(
|
||||||
|
'connectionString' => 'mysql:host=localhost;dbname=blog',
|
||||||
|
'emulatePrepare' => true,
|
||||||
|
'username' => 'root',
|
||||||
|
'password' => '',
|
||||||
|
'charset' => 'utf8',
|
||||||
|
'tablePrefix' => 'tbl_',
|
||||||
|
),
|
||||||
|
*/
|
||||||
|
'errorHandler'=>array(
|
||||||
|
// use 'site/error' action to display errors
|
||||||
|
'errorAction'=>'site/error',
|
||||||
|
),
|
||||||
|
'urlManager'=>array(
|
||||||
|
'urlFormat'=>'path',
|
||||||
|
'rules'=>array(
|
||||||
|
'post/<id:\d+>/<title:.*?>'=>'post/view',
|
||||||
|
'posts/<tag:.*?>'=>'post/index',
|
||||||
|
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'log'=>array(
|
||||||
|
'class'=>'CLogRouter',
|
||||||
|
'routes'=>array(
|
||||||
|
array(
|
||||||
|
'class'=>'CFileLogRoute',
|
||||||
|
'levels'=>'error, warning',
|
||||||
|
),
|
||||||
|
// uncomment the following to show log messages on web pages
|
||||||
|
/*
|
||||||
|
array(
|
||||||
|
'class'=>'CWebLogRoute',
|
||||||
|
),
|
||||||
|
*/
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// application-level parameters that can be accessed
|
||||||
|
// using Yii::app()->params['paramName']
|
||||||
|
'params'=>require(dirname(__FILE__).'/params.php'),
|
||||||
|
);
|
19
demos/blog/protected/config/params.php
Normal file
19
demos/blog/protected/config/params.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// this contains the application parameters that can be maintained via GUI
|
||||||
|
return array(
|
||||||
|
// this is displayed in the header section
|
||||||
|
'title'=>'My Yii Blog',
|
||||||
|
// this is used in error pages
|
||||||
|
'adminEmail'=>'webmaster@example.com',
|
||||||
|
// number of posts displayed per page
|
||||||
|
'postsPerPage'=>10,
|
||||||
|
// maximum number of comments that can be displayed in recent comments portlet
|
||||||
|
'recentCommentCount'=>10,
|
||||||
|
// maximum number of tags that can be displayed in tag cloud portlet
|
||||||
|
'tagCloudCount'=>20,
|
||||||
|
// whether post comments need to be approved before published
|
||||||
|
'commentNeedApproval'=>true,
|
||||||
|
// the copyright information displayed in the footer section
|
||||||
|
'copyrightInfo'=>'Copyright © 2009 by My Company.',
|
||||||
|
);
|
25
demos/blog/protected/config/test.php
Normal file
25
demos/blog/protected/config/test.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return CMap::mergeArray(
|
||||||
|
require(dirname(__FILE__).'/main.php'),
|
||||||
|
array(
|
||||||
|
'components'=>array(
|
||||||
|
'fixture'=>array(
|
||||||
|
'class'=>'system.test.CDbFixtureManager',
|
||||||
|
),
|
||||||
|
'db'=>array(
|
||||||
|
'connectionString'=>'sqlite:'.dirname(__FILE__).'/../data/blog-test.db',
|
||||||
|
),
|
||||||
|
// uncomment the following to use a MySQL database
|
||||||
|
/*
|
||||||
|
'db'=>array(
|
||||||
|
'connectionString' => 'mysql:host=localhost;dbname=blog-test',
|
||||||
|
'emulatePrepare' => true,
|
||||||
|
'username' => 'root',
|
||||||
|
'password' => '',
|
||||||
|
'charset' => 'utf8',
|
||||||
|
),
|
||||||
|
*/
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
130
demos/blog/protected/controllers/CommentController.php
Normal file
130
demos/blog/protected/controllers/CommentController.php
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class CommentController extends Controller
|
||||||
|
{
|
||||||
|
public $layout='column2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var CActiveRecord the currently loaded data model instance.
|
||||||
|
*/
|
||||||
|
private $_model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array action filters
|
||||||
|
*/
|
||||||
|
public function filters()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'accessControl', // perform access control for CRUD operations
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the access control rules.
|
||||||
|
* This method is used by the 'accessControl' filter.
|
||||||
|
* @return array access control rules
|
||||||
|
*/
|
||||||
|
public function accessRules()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('allow', // allow authenticated users to access all actions
|
||||||
|
'users'=>array('@'),
|
||||||
|
),
|
||||||
|
array('deny', // deny all users
|
||||||
|
'users'=>array('*'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates a particular model.
|
||||||
|
* If update is successful, the browser will be redirected to the 'view' page.
|
||||||
|
*/
|
||||||
|
public function actionUpdate()
|
||||||
|
{
|
||||||
|
$model=$this->loadModel();
|
||||||
|
if(isset($_POST['ajax']) && $_POST['ajax']==='comment-form')
|
||||||
|
{
|
||||||
|
echo CActiveForm::validate($model);
|
||||||
|
Yii::app()->end();
|
||||||
|
}
|
||||||
|
if(isset($_POST['Comment']))
|
||||||
|
{
|
||||||
|
$model->attributes=$_POST['Comment'];
|
||||||
|
if($model->save())
|
||||||
|
$this->redirect(array('index'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->render('update',array(
|
||||||
|
'model'=>$model,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a particular model.
|
||||||
|
* If deletion is successful, the browser will be redirected to the 'index' page.
|
||||||
|
*/
|
||||||
|
public function actionDelete()
|
||||||
|
{
|
||||||
|
if(Yii::app()->request->isPostRequest)
|
||||||
|
{
|
||||||
|
// we only allow deletion via POST request
|
||||||
|
$this->loadModel()->delete();
|
||||||
|
|
||||||
|
// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
|
||||||
|
if(!isset($_POST['ajax']))
|
||||||
|
$this->redirect(array('index'));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists all models.
|
||||||
|
*/
|
||||||
|
public function actionIndex()
|
||||||
|
{
|
||||||
|
$dataProvider=new CActiveDataProvider('Comment', array(
|
||||||
|
'criteria'=>array(
|
||||||
|
'with'=>'post',
|
||||||
|
'order'=>'t.status, t.create_time DESC',
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->render('index',array(
|
||||||
|
'dataProvider'=>$dataProvider,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Approves a particular comment.
|
||||||
|
* If approval is successful, the browser will be redirected to the comment index page.
|
||||||
|
*/
|
||||||
|
public function actionApprove()
|
||||||
|
{
|
||||||
|
if(Yii::app()->request->isPostRequest)
|
||||||
|
{
|
||||||
|
$comment=$this->loadModel();
|
||||||
|
$comment->approve();
|
||||||
|
$this->redirect(array('index'));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the data model based on the primary key given in the GET variable.
|
||||||
|
* If the data model is not found, an HTTP exception will be raised.
|
||||||
|
*/
|
||||||
|
public function loadModel()
|
||||||
|
{
|
||||||
|
if($this->_model===null)
|
||||||
|
{
|
||||||
|
if(isset($_GET['id']))
|
||||||
|
$this->_model=Comment::model()->findbyPk($_GET['id']);
|
||||||
|
if($this->_model===null)
|
||||||
|
throw new CHttpException(404,'The requested page does not exist.');
|
||||||
|
}
|
||||||
|
return $this->_model;
|
||||||
|
}
|
||||||
|
}
|
216
demos/blog/protected/controllers/PostController.php
Normal file
216
demos/blog/protected/controllers/PostController.php
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class PostController extends Controller
|
||||||
|
{
|
||||||
|
public $layout='column2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var CActiveRecord the currently loaded data model instance.
|
||||||
|
*/
|
||||||
|
private $_model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array action filters
|
||||||
|
*/
|
||||||
|
public function filters()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'accessControl', // perform access control for CRUD operations
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the access control rules.
|
||||||
|
* This method is used by the 'accessControl' filter.
|
||||||
|
* @return array access control rules
|
||||||
|
*/
|
||||||
|
public function accessRules()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('allow', // allow all users to access 'index' and 'view' actions.
|
||||||
|
'actions'=>array('index','view'),
|
||||||
|
'users'=>array('*'),
|
||||||
|
),
|
||||||
|
array('allow', // allow authenticated users to access all actions
|
||||||
|
'users'=>array('@'),
|
||||||
|
),
|
||||||
|
array('deny', // deny all users
|
||||||
|
'users'=>array('*'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a particular model.
|
||||||
|
*/
|
||||||
|
public function actionView()
|
||||||
|
{
|
||||||
|
$post=$this->loadModel();
|
||||||
|
$comment=$this->newComment($post);
|
||||||
|
|
||||||
|
$this->render('view',array(
|
||||||
|
'model'=>$post,
|
||||||
|
'comment'=>$comment,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new model.
|
||||||
|
* If creation is successful, the browser will be redirected to the 'view' page.
|
||||||
|
*/
|
||||||
|
public function actionCreate()
|
||||||
|
{
|
||||||
|
$model=new Post;
|
||||||
|
if(isset($_POST['Post']))
|
||||||
|
{
|
||||||
|
$model->attributes=$_POST['Post'];
|
||||||
|
if($model->save())
|
||||||
|
$this->redirect(array('view','id'=>$model->id));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->render('create',array(
|
||||||
|
'model'=>$model,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates a particular model.
|
||||||
|
* If update is successful, the browser will be redirected to the 'view' page.
|
||||||
|
*/
|
||||||
|
public function actionUpdate()
|
||||||
|
{
|
||||||
|
$model=$this->loadModel();
|
||||||
|
if(isset($_POST['Post']))
|
||||||
|
{
|
||||||
|
$model->attributes=$_POST['Post'];
|
||||||
|
if($model->save())
|
||||||
|
$this->redirect(array('view','id'=>$model->id));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->render('update',array(
|
||||||
|
'model'=>$model,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a particular model.
|
||||||
|
* If deletion is successful, the browser will be redirected to the 'index' page.
|
||||||
|
*/
|
||||||
|
public function actionDelete()
|
||||||
|
{
|
||||||
|
if(Yii::app()->request->isPostRequest)
|
||||||
|
{
|
||||||
|
// we only allow deletion via POST request
|
||||||
|
$this->loadModel()->delete();
|
||||||
|
|
||||||
|
// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
|
||||||
|
if(!isset($_GET['ajax']))
|
||||||
|
$this->redirect(array('index'));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists all models.
|
||||||
|
*/
|
||||||
|
public function actionIndex()
|
||||||
|
{
|
||||||
|
$criteria=new CDbCriteria(array(
|
||||||
|
'condition'=>'status='.Post::STATUS_PUBLISHED,
|
||||||
|
'order'=>'update_time DESC',
|
||||||
|
'with'=>'commentCount',
|
||||||
|
));
|
||||||
|
if(isset($_GET['tag']))
|
||||||
|
$criteria->addSearchCondition('tags',$_GET['tag']);
|
||||||
|
|
||||||
|
$dataProvider=new CActiveDataProvider('Post', array(
|
||||||
|
'pagination'=>array(
|
||||||
|
'pageSize'=>Yii::app()->params['postsPerPage'],
|
||||||
|
),
|
||||||
|
'criteria'=>$criteria,
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->render('index',array(
|
||||||
|
'dataProvider'=>$dataProvider,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages all models.
|
||||||
|
*/
|
||||||
|
public function actionAdmin()
|
||||||
|
{
|
||||||
|
$model=new Post('search');
|
||||||
|
if(isset($_GET['Post']))
|
||||||
|
$model->attributes=$_GET['Post'];
|
||||||
|
$this->render('admin',array(
|
||||||
|
'model'=>$model,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suggests tags based on the current user input.
|
||||||
|
* This is called via AJAX when the user is entering the tags input.
|
||||||
|
*/
|
||||||
|
public function actionSuggestTags()
|
||||||
|
{
|
||||||
|
if(isset($_GET['q']) && ($keyword=trim($_GET['q']))!=='')
|
||||||
|
{
|
||||||
|
$tags=Tag::model()->suggestTags($keyword);
|
||||||
|
if($tags!==array())
|
||||||
|
echo implode("\n",$tags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the data model based on the primary key given in the GET variable.
|
||||||
|
* If the data model is not found, an HTTP exception will be raised.
|
||||||
|
*/
|
||||||
|
public function loadModel()
|
||||||
|
{
|
||||||
|
if($this->_model===null)
|
||||||
|
{
|
||||||
|
if(isset($_GET['id']))
|
||||||
|
{
|
||||||
|
if(Yii::app()->user->isGuest)
|
||||||
|
$condition='status='.Post::STATUS_PUBLISHED.' OR status='.Post::STATUS_ARCHIVED;
|
||||||
|
else
|
||||||
|
$condition='';
|
||||||
|
$this->_model=Post::model()->findByPk($_GET['id'], $condition);
|
||||||
|
}
|
||||||
|
if($this->_model===null)
|
||||||
|
throw new CHttpException(404,'The requested page does not exist.');
|
||||||
|
}
|
||||||
|
return $this->_model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new comment.
|
||||||
|
* This method attempts to create a new comment based on the user input.
|
||||||
|
* If the comment is successfully created, the browser will be redirected
|
||||||
|
* to show the created comment.
|
||||||
|
* @param Post the post that the new comment belongs to
|
||||||
|
* @return Comment the comment instance
|
||||||
|
*/
|
||||||
|
protected function newComment($post)
|
||||||
|
{
|
||||||
|
$comment=new Comment;
|
||||||
|
if(isset($_POST['ajax']) && $_POST['ajax']==='comment-form')
|
||||||
|
{
|
||||||
|
echo CActiveForm::validate($comment);
|
||||||
|
Yii::app()->end();
|
||||||
|
}
|
||||||
|
if(isset($_POST['Comment']))
|
||||||
|
{
|
||||||
|
$comment->attributes=$_POST['Comment'];
|
||||||
|
if($post->addComment($comment))
|
||||||
|
{
|
||||||
|
if($comment->status==Comment::STATUS_PENDING)
|
||||||
|
Yii::app()->user->setFlash('commentSubmitted','Thank you for your comment. Your comment will be posted once it is approved.');
|
||||||
|
$this->refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $comment;
|
||||||
|
}
|
||||||
|
}
|
97
demos/blog/protected/controllers/SiteController.php
Normal file
97
demos/blog/protected/controllers/SiteController.php
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class SiteController extends Controller
|
||||||
|
{
|
||||||
|
public $layout='column1';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declares class-based actions.
|
||||||
|
*/
|
||||||
|
public function actions()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
// captcha action renders the CAPTCHA image displayed on the contact page
|
||||||
|
'captcha'=>array(
|
||||||
|
'class'=>'CCaptchaAction',
|
||||||
|
'backColor'=>0xFFFFFF,
|
||||||
|
),
|
||||||
|
// page action renders "static" pages stored under 'protected/views/site/pages'
|
||||||
|
// They can be accessed via: index.php?r=site/page&view=FileName
|
||||||
|
'page'=>array(
|
||||||
|
'class'=>'CViewAction',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the action to handle external exceptions.
|
||||||
|
*/
|
||||||
|
public function actionError()
|
||||||
|
{
|
||||||
|
if($error=Yii::app()->errorHandler->error)
|
||||||
|
{
|
||||||
|
if(Yii::app()->request->isAjaxRequest)
|
||||||
|
echo $error['message'];
|
||||||
|
else
|
||||||
|
$this->render('error', $error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the contact page
|
||||||
|
*/
|
||||||
|
public function actionContact()
|
||||||
|
{
|
||||||
|
$model=new ContactForm;
|
||||||
|
if(isset($_POST['ContactForm']))
|
||||||
|
{
|
||||||
|
$model->attributes=$_POST['ContactForm'];
|
||||||
|
if($model->validate())
|
||||||
|
{
|
||||||
|
$headers="From: {$model->email}\r\nReply-To: {$model->email}";
|
||||||
|
mail(Yii::app()->params['adminEmail'],$model->subject,$model->body,$headers);
|
||||||
|
Yii::app()->user->setFlash('contact','Thank you for contacting us. We will respond to you as soon as possible.');
|
||||||
|
$this->refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->render('contact',array('model'=>$model));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the login page
|
||||||
|
*/
|
||||||
|
public function actionLogin()
|
||||||
|
{
|
||||||
|
if (!defined('CRYPT_BLOWFISH')||!CRYPT_BLOWFISH)
|
||||||
|
throw new CHttpException(500,"This application requires that PHP was compiled with Blowfish support for crypt().");
|
||||||
|
|
||||||
|
$model=new LoginForm;
|
||||||
|
|
||||||
|
// if it is ajax validation request
|
||||||
|
if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')
|
||||||
|
{
|
||||||
|
echo CActiveForm::validate($model);
|
||||||
|
Yii::app()->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
// collect user input data
|
||||||
|
if(isset($_POST['LoginForm']))
|
||||||
|
{
|
||||||
|
$model->attributes=$_POST['LoginForm'];
|
||||||
|
// validate user input and redirect to the previous page if valid
|
||||||
|
if($model->validate() && $model->login())
|
||||||
|
$this->redirect(Yii::app()->user->returnUrl);
|
||||||
|
}
|
||||||
|
// display the login form
|
||||||
|
$this->render('login',array('model'=>$model));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs out the current user and redirect to homepage.
|
||||||
|
*/
|
||||||
|
public function actionLogout()
|
||||||
|
{
|
||||||
|
Yii::app()->user->logout();
|
||||||
|
$this->redirect(Yii::app()->homeUrl);
|
||||||
|
}
|
||||||
|
}
|
BIN
demos/blog/protected/data/blog-test.db
Normal file
BIN
demos/blog/protected/data/blog-test.db
Normal file
Binary file not shown.
BIN
demos/blog/protected/data/blog.db
Normal file
BIN
demos/blog/protected/data/blog.db
Normal file
Binary file not shown.
13
demos/blog/protected/data/dbgen.php
Normal file
13
demos/blog/protected/data/dbgen.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$dbFile=dirname(__FILE__).'/blog.db';
|
||||||
|
$sqlFile=dirname(__FILE__).'/schema.sqlite.sql';
|
||||||
|
|
||||||
|
@unlink($dbFile);
|
||||||
|
$db=new PDO('sqlite:'.$dbFile);
|
||||||
|
$sqls=file_get_contents($sqlFile);
|
||||||
|
foreach(explode(';',$sqls) as $sql)
|
||||||
|
{
|
||||||
|
if(trim($sql)!=='')
|
||||||
|
$db->exec($sql);
|
||||||
|
}
|
70
demos/blog/protected/data/schema.mysql.sql
Normal file
70
demos/blog/protected/data/schema.mysql.sql
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
CREATE TABLE tbl_lookup
|
||||||
|
(
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
name VARCHAR(128) NOT NULL,
|
||||||
|
code INTEGER NOT NULL,
|
||||||
|
type VARCHAR(128) NOT NULL,
|
||||||
|
position INTEGER NOT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||||
|
|
||||||
|
CREATE TABLE tbl_user
|
||||||
|
(
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
username VARCHAR(128) NOT NULL,
|
||||||
|
password VARCHAR(128) NOT NULL,
|
||||||
|
email VARCHAR(128) NOT NULL,
|
||||||
|
profile TEXT
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||||
|
|
||||||
|
CREATE TABLE tbl_post
|
||||||
|
(
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
title VARCHAR(128) NOT NULL,
|
||||||
|
content TEXT NOT NULL,
|
||||||
|
tags TEXT,
|
||||||
|
status INTEGER NOT NULL,
|
||||||
|
create_time INTEGER,
|
||||||
|
update_time INTEGER,
|
||||||
|
author_id INTEGER NOT NULL,
|
||||||
|
CONSTRAINT FK_post_author FOREIGN KEY (author_id)
|
||||||
|
REFERENCES tbl_user (id) ON DELETE CASCADE ON UPDATE RESTRICT
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||||
|
|
||||||
|
CREATE TABLE tbl_comment
|
||||||
|
(
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
content TEXT NOT NULL,
|
||||||
|
status INTEGER NOT NULL,
|
||||||
|
create_time INTEGER,
|
||||||
|
author VARCHAR(128) NOT NULL,
|
||||||
|
email VARCHAR(128) NOT NULL,
|
||||||
|
url VARCHAR(128),
|
||||||
|
post_id INTEGER NOT NULL,
|
||||||
|
CONSTRAINT FK_comment_post FOREIGN KEY (post_id)
|
||||||
|
REFERENCES tbl_post (id) ON DELETE CASCADE ON UPDATE RESTRICT
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||||
|
|
||||||
|
CREATE TABLE tbl_tag
|
||||||
|
(
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
name VARCHAR(128) NOT NULL,
|
||||||
|
frequency INTEGER DEFAULT 1
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||||
|
|
||||||
|
INSERT INTO tbl_lookup (name, type, code, position) VALUES ('Draft', 'PostStatus', 1, 1);
|
||||||
|
INSERT INTO tbl_lookup (name, type, code, position) VALUES ('Published', 'PostStatus', 2, 2);
|
||||||
|
INSERT INTO tbl_lookup (name, type, code, position) VALUES ('Archived', 'PostStatus', 3, 3);
|
||||||
|
INSERT INTO tbl_lookup (name, type, code, position) VALUES ('Pending Approval', 'CommentStatus', 1, 1);
|
||||||
|
INSERT INTO tbl_lookup (name, type, code, position) VALUES ('Approved', 'CommentStatus', 2, 2);
|
||||||
|
|
||||||
|
INSERT INTO tbl_user (username, password, email) VALUES ('demo','$2a$10$JTJf6/XqC94rrOtzuF397OHa4mbmZrVTBOQCmYD9U.obZRUut4BoC','webmaster@example.com');
|
||||||
|
INSERT INTO tbl_post (title, content, status, create_time, update_time, author_id, tags) VALUES ('Welcome!','This blog system is developed using Yii. It is meant to demonstrate how to use Yii to build a complete real-world application. Complete source code may be found in the Yii releases.
|
||||||
|
|
||||||
|
Feel free to try this system by writing new posts and posting comments.',2,1230952187,1230952187,1,'yii, blog');
|
||||||
|
INSERT INTO tbl_post (title, content, status, create_time, update_time, author_id, tags) VALUES ('A Test Post', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', 2,1230952187,1230952187,1,'test');
|
||||||
|
|
||||||
|
INSERT INTO tbl_comment (content, status, create_time, author, email, post_id) VALUES ('This is a test comment.', 2, 1230952187, 'Tester', 'tester@example.com', 2);
|
||||||
|
|
||||||
|
INSERT INTO tbl_tag (name) VALUES ('yii');
|
||||||
|
INSERT INTO tbl_tag (name) VALUES ('blog');
|
||||||
|
INSERT INTO tbl_tag (name) VALUES ('test');
|
70
demos/blog/protected/data/schema.sqlite.sql
Normal file
70
demos/blog/protected/data/schema.sqlite.sql
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
CREATE TABLE tbl_lookup
|
||||||
|
(
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name VARCHAR(128) NOT NULL,
|
||||||
|
code INTEGER NOT NULL,
|
||||||
|
type VARCHAR(128) NOT NULL,
|
||||||
|
position INTEGER NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE tbl_user
|
||||||
|
(
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
username VARCHAR(128) NOT NULL,
|
||||||
|
password VARCHAR(128) NOT NULL,
|
||||||
|
email VARCHAR(128) NOT NULL,
|
||||||
|
profile TEXT
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE tbl_post
|
||||||
|
(
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
title VARCHAR(128) NOT NULL,
|
||||||
|
content TEXT NOT NULL,
|
||||||
|
tags TEXT,
|
||||||
|
status INTEGER NOT NULL,
|
||||||
|
create_time INTEGER,
|
||||||
|
update_time INTEGER,
|
||||||
|
author_id INTEGER NOT NULL,
|
||||||
|
CONSTRAINT FK_post_author FOREIGN KEY (author_id)
|
||||||
|
REFERENCES tbl_user (id) ON DELETE CASCADE ON UPDATE RESTRICT
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE tbl_comment
|
||||||
|
(
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
content TEXT NOT NULL,
|
||||||
|
status INTEGER NOT NULL,
|
||||||
|
create_time INTEGER,
|
||||||
|
author VARCHAR(128) NOT NULL,
|
||||||
|
email VARCHAR(128) NOT NULL,
|
||||||
|
url VARCHAR(128),
|
||||||
|
post_id INTEGER NOT NULL,
|
||||||
|
CONSTRAINT FK_comment_post FOREIGN KEY (post_id)
|
||||||
|
REFERENCES tbl_post (id) ON DELETE CASCADE ON UPDATE RESTRICT
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE tbl_tag
|
||||||
|
(
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name VARCHAR(128) NOT NULL,
|
||||||
|
frequency INTEGER DEFAULT 1
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO tbl_lookup (name, type, code, position) VALUES ('Draft', 'PostStatus', 1, 1);
|
||||||
|
INSERT INTO tbl_lookup (name, type, code, position) VALUES ('Published', 'PostStatus', 2, 2);
|
||||||
|
INSERT INTO tbl_lookup (name, type, code, position) VALUES ('Archived', 'PostStatus', 3, 3);
|
||||||
|
INSERT INTO tbl_lookup (name, type, code, position) VALUES ('Pending Approval', 'CommentStatus', 1, 1);
|
||||||
|
INSERT INTO tbl_lookup (name, type, code, position) VALUES ('Approved', 'CommentStatus', 2, 2);
|
||||||
|
|
||||||
|
INSERT INTO tbl_user (username, password, email) VALUES ('demo','$2a$10$JTJf6/XqC94rrOtzuF397OHa4mbmZrVTBOQCmYD9U.obZRUut4BoC','webmaster@example.com');
|
||||||
|
INSERT INTO tbl_post (title, content, status, create_time, update_time, author_id, tags) VALUES ('Welcome!','This blog system is developed using Yii. It is meant to demonstrate how to use Yii to build a complete real-world application. Complete source code may be found in the Yii releases.
|
||||||
|
|
||||||
|
Feel free to try this system by writing new posts and leaving comments.',2,1230952187,1230952187,1,'yii, blog');
|
||||||
|
INSERT INTO tbl_post (title, content, status, create_time, update_time, author_id, tags) VALUES ('A Test Post', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', 2,1230952187,1230952187,1,'test');
|
||||||
|
|
||||||
|
INSERT INTO tbl_comment (content, status, create_time, author, email, post_id) VALUES ('This is a test comment.', 2, 1230952187, 'Tester', 'tester@example.com', 2);
|
||||||
|
|
||||||
|
INSERT INTO tbl_tag (name) VALUES ('yii');
|
||||||
|
INSERT INTO tbl_tag (name) VALUES ('blog');
|
||||||
|
INSERT INTO tbl_tag (name) VALUES ('test');
|
148
demos/blog/protected/models/Comment.php
Normal file
148
demos/blog/protected/models/Comment.php
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Comment extends CActiveRecord
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The followings are the available columns in table 'tbl_comment':
|
||||||
|
* @var integer $id
|
||||||
|
* @var string $content
|
||||||
|
* @var integer $status
|
||||||
|
* @var integer $create_time
|
||||||
|
* @var string $author
|
||||||
|
* @var string $email
|
||||||
|
* @var string $url
|
||||||
|
* @var integer $post_id
|
||||||
|
*/
|
||||||
|
const STATUS_PENDING=1;
|
||||||
|
const STATUS_APPROVED=2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the static model of the specified AR class.
|
||||||
|
* @return CActiveRecord the static model class
|
||||||
|
*/
|
||||||
|
public static function model($className=__CLASS__)
|
||||||
|
{
|
||||||
|
return parent::model($className);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string the associated database table name
|
||||||
|
*/
|
||||||
|
public function tableName()
|
||||||
|
{
|
||||||
|
return '{{comment}}';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array validation rules for model attributes.
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
// NOTE: you should only define rules for those attributes that
|
||||||
|
// will receive user inputs.
|
||||||
|
return array(
|
||||||
|
array('content, author, email', 'required'),
|
||||||
|
array('author, email, url', 'length', 'max'=>128),
|
||||||
|
array('email','email'),
|
||||||
|
array('url','url'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array relational rules.
|
||||||
|
*/
|
||||||
|
public function relations()
|
||||||
|
{
|
||||||
|
// NOTE: you may need to adjust the relation name and the related
|
||||||
|
// class name for the relations automatically generated below.
|
||||||
|
return array(
|
||||||
|
'post' => array(self::BELONGS_TO, 'Post', 'post_id'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array customized attribute labels (name=>label)
|
||||||
|
*/
|
||||||
|
public function attributeLabels()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'id' => 'Id',
|
||||||
|
'content' => 'Comment',
|
||||||
|
'status' => 'Status',
|
||||||
|
'create_time' => 'Create Time',
|
||||||
|
'author' => 'Name',
|
||||||
|
'email' => 'Email',
|
||||||
|
'url' => 'Website',
|
||||||
|
'post_id' => 'Post',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Approves a comment.
|
||||||
|
*/
|
||||||
|
public function approve()
|
||||||
|
{
|
||||||
|
$this->status=Comment::STATUS_APPROVED;
|
||||||
|
$this->update(array('status'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Post the post that this comment belongs to. If null, the method
|
||||||
|
* will query for the post.
|
||||||
|
* @return string the permalink URL for this comment
|
||||||
|
*/
|
||||||
|
public function getUrl($post=null)
|
||||||
|
{
|
||||||
|
if($post===null)
|
||||||
|
$post=$this->post;
|
||||||
|
return $post->url.'#c'.$this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string the hyperlink display for the current comment's author
|
||||||
|
*/
|
||||||
|
public function getAuthorLink()
|
||||||
|
{
|
||||||
|
if(!empty($this->url))
|
||||||
|
return CHtml::link(CHtml::encode($this->author),$this->url);
|
||||||
|
else
|
||||||
|
return CHtml::encode($this->author);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return integer the number of comments that are pending approval
|
||||||
|
*/
|
||||||
|
public function getPendingCommentCount()
|
||||||
|
{
|
||||||
|
return $this->count('status='.self::STATUS_PENDING);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param integer the maximum number of comments that should be returned
|
||||||
|
* @return array the most recently added comments
|
||||||
|
*/
|
||||||
|
public function findRecentComments($limit=10)
|
||||||
|
{
|
||||||
|
return $this->with('post')->findAll(array(
|
||||||
|
'condition'=>'t.status='.self::STATUS_APPROVED,
|
||||||
|
'order'=>'t.create_time DESC',
|
||||||
|
'limit'=>$limit,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is invoked before the record is saved.
|
||||||
|
* @return boolean whether the record should be saved.
|
||||||
|
*/
|
||||||
|
protected function beforeSave()
|
||||||
|
{
|
||||||
|
if(parent::beforeSave())
|
||||||
|
{
|
||||||
|
if($this->isNewRecord)
|
||||||
|
$this->create_time=time();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
42
demos/blog/protected/models/ContactForm.php
Normal file
42
demos/blog/protected/models/ContactForm.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ContactForm class.
|
||||||
|
* ContactForm is the data structure for keeping
|
||||||
|
* contact form data. It is used by the 'contact' action of 'SiteController'.
|
||||||
|
*/
|
||||||
|
class ContactForm extends CFormModel
|
||||||
|
{
|
||||||
|
public $name;
|
||||||
|
public $email;
|
||||||
|
public $subject;
|
||||||
|
public $body;
|
||||||
|
public $verifyCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declares the validation rules.
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
// name, email, subject and body are required
|
||||||
|
array('name, email, subject, body', 'required'),
|
||||||
|
// email has to be a valid email address
|
||||||
|
array('email', 'email'),
|
||||||
|
// verifyCode needs to be entered correctly
|
||||||
|
array('verifyCode', 'captcha', 'allowEmpty'=>!CCaptcha::checkRequirements()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declares customized attribute labels.
|
||||||
|
* If not declared here, an attribute would have a label that is
|
||||||
|
* the same as its name with the first letter in upper case.
|
||||||
|
*/
|
||||||
|
public function attributeLabels()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'verifyCode'=>'Verification Code',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
74
demos/blog/protected/models/LoginForm.php
Normal file
74
demos/blog/protected/models/LoginForm.php
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LoginForm class.
|
||||||
|
* LoginForm is the data structure for keeping
|
||||||
|
* user login form data. It is used by the 'login' action of 'SiteController'.
|
||||||
|
*/
|
||||||
|
class LoginForm extends CFormModel
|
||||||
|
{
|
||||||
|
public $username;
|
||||||
|
public $password;
|
||||||
|
public $rememberMe;
|
||||||
|
|
||||||
|
private $_identity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declares the validation rules.
|
||||||
|
* The rules state that username and password are required,
|
||||||
|
* and password needs to be authenticated.
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
// username and password are required
|
||||||
|
array('username, password', 'required'),
|
||||||
|
// rememberMe needs to be a boolean
|
||||||
|
array('rememberMe', 'boolean'),
|
||||||
|
// password needs to be authenticated
|
||||||
|
array('password', 'authenticate'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declares attribute labels.
|
||||||
|
*/
|
||||||
|
public function attributeLabels()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'rememberMe'=>'Remember me next time',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticates the password.
|
||||||
|
* This is the 'authenticate' validator as declared in rules().
|
||||||
|
*/
|
||||||
|
public function authenticate($attribute,$params)
|
||||||
|
{
|
||||||
|
$this->_identity=new UserIdentity($this->username,$this->password);
|
||||||
|
if(!$this->_identity->authenticate())
|
||||||
|
$this->addError('password','Incorrect username or password.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs in the user using the given username and password in the model.
|
||||||
|
* @return boolean whether login is successful
|
||||||
|
*/
|
||||||
|
public function login()
|
||||||
|
{
|
||||||
|
if($this->_identity===null)
|
||||||
|
{
|
||||||
|
$this->_identity=new UserIdentity($this->username,$this->password);
|
||||||
|
$this->_identity->authenticate();
|
||||||
|
}
|
||||||
|
if($this->_identity->errorCode===UserIdentity::ERROR_NONE)
|
||||||
|
{
|
||||||
|
$duration=$this->rememberMe ? 3600*24*30 : 0; // 30 days
|
||||||
|
Yii::app()->user->login($this->_identity,$duration);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
76
demos/blog/protected/models/Lookup.php
Normal file
76
demos/blog/protected/models/Lookup.php
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Lookup extends CActiveRecord
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The followings are the available columns in table 'tbl_lookup':
|
||||||
|
* @var integer $id
|
||||||
|
* @var string $object_type
|
||||||
|
* @var integer $code
|
||||||
|
* @var string $name_en
|
||||||
|
* @var string $name_fr
|
||||||
|
* @var integer $sequence
|
||||||
|
* @var integer $status
|
||||||
|
*/
|
||||||
|
|
||||||
|
private static $_items=array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the static model of the specified AR class.
|
||||||
|
* @return CActiveRecord the static model class
|
||||||
|
*/
|
||||||
|
public static function model($className=__CLASS__)
|
||||||
|
{
|
||||||
|
return parent::model($className);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string the associated database table name
|
||||||
|
*/
|
||||||
|
public function tableName()
|
||||||
|
{
|
||||||
|
return '{{lookup}}';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the items for the specified type.
|
||||||
|
* @param string item type (e.g. 'PostStatus').
|
||||||
|
* @return array item names indexed by item code. The items are order by their position values.
|
||||||
|
* An empty array is returned if the item type does not exist.
|
||||||
|
*/
|
||||||
|
public static function items($type)
|
||||||
|
{
|
||||||
|
if(!isset(self::$_items[$type]))
|
||||||
|
self::loadItems($type);
|
||||||
|
return self::$_items[$type];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the item name for the specified type and code.
|
||||||
|
* @param string the item type (e.g. 'PostStatus').
|
||||||
|
* @param integer the item code (corresponding to the 'code' column value)
|
||||||
|
* @return string the item name for the specified the code. False is returned if the item type or code does not exist.
|
||||||
|
*/
|
||||||
|
public static function item($type,$code)
|
||||||
|
{
|
||||||
|
if(!isset(self::$_items[$type]))
|
||||||
|
self::loadItems($type);
|
||||||
|
return isset(self::$_items[$type][$code]) ? self::$_items[$type][$code] : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the lookup items for the specified type from the database.
|
||||||
|
* @param string the item type
|
||||||
|
*/
|
||||||
|
private static function loadItems($type)
|
||||||
|
{
|
||||||
|
self::$_items[$type]=array();
|
||||||
|
$models=self::model()->findAll(array(
|
||||||
|
'condition'=>'type=:type',
|
||||||
|
'params'=>array(':type'=>$type),
|
||||||
|
'order'=>'position',
|
||||||
|
));
|
||||||
|
foreach($models as $model)
|
||||||
|
self::$_items[$type][$model->code]=$model->name;
|
||||||
|
}
|
||||||
|
}
|
202
demos/blog/protected/models/Post.php
Normal file
202
demos/blog/protected/models/Post.php
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Post extends CActiveRecord
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The followings are the available columns in table 'tbl_post':
|
||||||
|
* @var integer $id
|
||||||
|
* @var string $title
|
||||||
|
* @var string $content
|
||||||
|
* @var string $tags
|
||||||
|
* @var integer $status
|
||||||
|
* @var integer $create_time
|
||||||
|
* @var integer $update_time
|
||||||
|
* @var integer $author_id
|
||||||
|
*/
|
||||||
|
const STATUS_DRAFT=1;
|
||||||
|
const STATUS_PUBLISHED=2;
|
||||||
|
const STATUS_ARCHIVED=3;
|
||||||
|
|
||||||
|
private $_oldTags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the static model of the specified AR class.
|
||||||
|
* @return CActiveRecord the static model class
|
||||||
|
*/
|
||||||
|
public static function model($className=__CLASS__)
|
||||||
|
{
|
||||||
|
return parent::model($className);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string the associated database table name
|
||||||
|
*/
|
||||||
|
public function tableName()
|
||||||
|
{
|
||||||
|
return '{{post}}';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array validation rules for model attributes.
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
// NOTE: you should only define rules for those attributes that
|
||||||
|
// will receive user inputs.
|
||||||
|
return array(
|
||||||
|
array('title, content, status', 'required'),
|
||||||
|
array('status', 'in', 'range'=>array(1,2,3)),
|
||||||
|
array('title', 'length', 'max'=>128),
|
||||||
|
array('tags', 'match', 'pattern'=>'/^[\w\s,]+$/', 'message'=>'Tags can only contain word characters.'),
|
||||||
|
array('tags', 'normalizeTags'),
|
||||||
|
|
||||||
|
array('title, status', 'safe', 'on'=>'search'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array relational rules.
|
||||||
|
*/
|
||||||
|
public function relations()
|
||||||
|
{
|
||||||
|
// NOTE: you may need to adjust the relation name and the related
|
||||||
|
// class name for the relations automatically generated below.
|
||||||
|
return array(
|
||||||
|
'author' => array(self::BELONGS_TO, 'User', 'author_id'),
|
||||||
|
'comments' => array(self::HAS_MANY, 'Comment', 'post_id', 'condition'=>'comments.status='.Comment::STATUS_APPROVED, 'order'=>'comments.create_time DESC'),
|
||||||
|
'commentCount' => array(self::STAT, 'Comment', 'post_id', 'condition'=>'status='.Comment::STATUS_APPROVED),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array customized attribute labels (name=>label)
|
||||||
|
*/
|
||||||
|
public function attributeLabels()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'id' => 'Id',
|
||||||
|
'title' => 'Title',
|
||||||
|
'content' => 'Content',
|
||||||
|
'tags' => 'Tags',
|
||||||
|
'status' => 'Status',
|
||||||
|
'create_time' => 'Create Time',
|
||||||
|
'update_time' => 'Update Time',
|
||||||
|
'author_id' => 'Author',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string the URL that shows the detail of the post
|
||||||
|
*/
|
||||||
|
public function getUrl()
|
||||||
|
{
|
||||||
|
return Yii::app()->createUrl('post/view', array(
|
||||||
|
'id'=>$this->id,
|
||||||
|
'title'=>$this->title,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array a list of links that point to the post list filtered by every tag of this post
|
||||||
|
*/
|
||||||
|
public function getTagLinks()
|
||||||
|
{
|
||||||
|
$links=array();
|
||||||
|
foreach(Tag::string2array($this->tags) as $tag)
|
||||||
|
$links[]=CHtml::link(CHtml::encode($tag), array('post/index', 'tag'=>$tag));
|
||||||
|
return $links;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes the user-entered tags.
|
||||||
|
*/
|
||||||
|
public function normalizeTags($attribute,$params)
|
||||||
|
{
|
||||||
|
$this->tags=Tag::array2string(array_unique(Tag::string2array($this->tags)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new comment to this post.
|
||||||
|
* This method will set status and post_id of the comment accordingly.
|
||||||
|
* @param Comment the comment to be added
|
||||||
|
* @return boolean whether the comment is saved successfully
|
||||||
|
*/
|
||||||
|
public function addComment($comment)
|
||||||
|
{
|
||||||
|
if(Yii::app()->params['commentNeedApproval'])
|
||||||
|
$comment->status=Comment::STATUS_PENDING;
|
||||||
|
else
|
||||||
|
$comment->status=Comment::STATUS_APPROVED;
|
||||||
|
$comment->post_id=$this->id;
|
||||||
|
return $comment->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is invoked when a record is populated with data from a find() call.
|
||||||
|
*/
|
||||||
|
protected function afterFind()
|
||||||
|
{
|
||||||
|
parent::afterFind();
|
||||||
|
$this->_oldTags=$this->tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is invoked before the record is saved.
|
||||||
|
* @return boolean whether the record should be saved.
|
||||||
|
*/
|
||||||
|
protected function beforeSave()
|
||||||
|
{
|
||||||
|
if(parent::beforeSave())
|
||||||
|
{
|
||||||
|
if($this->isNewRecord)
|
||||||
|
{
|
||||||
|
$this->create_time=$this->update_time=time();
|
||||||
|
$this->author_id=Yii::app()->user->id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
$this->update_time=time();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is invoked after the record is saved.
|
||||||
|
*/
|
||||||
|
protected function afterSave()
|
||||||
|
{
|
||||||
|
parent::afterSave();
|
||||||
|
Tag::model()->updateFrequency($this->_oldTags, $this->tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is invoked after the record is deleted.
|
||||||
|
*/
|
||||||
|
protected function afterDelete()
|
||||||
|
{
|
||||||
|
parent::afterDelete();
|
||||||
|
Comment::model()->deleteAll('post_id='.$this->id);
|
||||||
|
Tag::model()->updateFrequency($this->tags, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of posts based on the current search/filter conditions.
|
||||||
|
* @return CActiveDataProvider the data provider that can return the needed posts.
|
||||||
|
*/
|
||||||
|
public function search()
|
||||||
|
{
|
||||||
|
$criteria=new CDbCriteria;
|
||||||
|
|
||||||
|
$criteria->compare('title',$this->title,true);
|
||||||
|
|
||||||
|
$criteria->compare('status',$this->status);
|
||||||
|
|
||||||
|
return new CActiveDataProvider('Post', array(
|
||||||
|
'criteria'=>$criteria,
|
||||||
|
'sort'=>array(
|
||||||
|
'defaultOrder'=>'status, update_time DESC',
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
159
demos/blog/protected/models/Tag.php
Normal file
159
demos/blog/protected/models/Tag.php
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Tag extends CActiveRecord
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The followings are the available columns in table 'tbl_tag':
|
||||||
|
* @var integer $id
|
||||||
|
* @var string $name
|
||||||
|
* @var integer $frequency
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the static model of the specified AR class.
|
||||||
|
* @return CActiveRecord the static model class
|
||||||
|
*/
|
||||||
|
public static function model($className=__CLASS__)
|
||||||
|
{
|
||||||
|
return parent::model($className);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string the associated database table name
|
||||||
|
*/
|
||||||
|
public function tableName()
|
||||||
|
{
|
||||||
|
return '{{tag}}';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array validation rules for model attributes.
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
// NOTE: you should only define rules for those attributes that
|
||||||
|
// will receive user inputs.
|
||||||
|
return array(
|
||||||
|
array('name', 'required'),
|
||||||
|
array('frequency', 'numerical', 'integerOnly'=>true),
|
||||||
|
array('name', 'length', 'max'=>128),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array relational rules.
|
||||||
|
*/
|
||||||
|
public function relations()
|
||||||
|
{
|
||||||
|
// NOTE: you may need to adjust the relation name and the related
|
||||||
|
// class name for the relations automatically generated below.
|
||||||
|
return array(
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array customized attribute labels (name=>label)
|
||||||
|
*/
|
||||||
|
public function attributeLabels()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'id' => 'Id',
|
||||||
|
'name' => 'Name',
|
||||||
|
'frequency' => 'Frequency',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns tag names and their corresponding weights.
|
||||||
|
* Only the tags with the top weights will be returned.
|
||||||
|
* @param integer the maximum number of tags that should be returned
|
||||||
|
* @return array weights indexed by tag names.
|
||||||
|
*/
|
||||||
|
public function findTagWeights($limit=20)
|
||||||
|
{
|
||||||
|
$models=$this->findAll(array(
|
||||||
|
'order'=>'frequency DESC',
|
||||||
|
'limit'=>$limit,
|
||||||
|
));
|
||||||
|
|
||||||
|
$total=0;
|
||||||
|
foreach($models as $model)
|
||||||
|
$total+=$model->frequency;
|
||||||
|
|
||||||
|
$tags=array();
|
||||||
|
if($total>0)
|
||||||
|
{
|
||||||
|
foreach($models as $model)
|
||||||
|
$tags[$model->name]=8+(int)(16*$model->frequency/($total+10));
|
||||||
|
ksort($tags);
|
||||||
|
}
|
||||||
|
return $tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suggests a list of existing tags matching the specified keyword.
|
||||||
|
* @param string the keyword to be matched
|
||||||
|
* @param integer maximum number of tags to be returned
|
||||||
|
* @return array list of matching tag names
|
||||||
|
*/
|
||||||
|
public function suggestTags($keyword,$limit=20)
|
||||||
|
{
|
||||||
|
$tags=$this->findAll(array(
|
||||||
|
'condition'=>'name LIKE :keyword',
|
||||||
|
'order'=>'frequency DESC, Name',
|
||||||
|
'limit'=>$limit,
|
||||||
|
'params'=>array(
|
||||||
|
':keyword'=>'%'.strtr($keyword,array('%'=>'\%', '_'=>'\_', '\\'=>'\\\\')).'%',
|
||||||
|
),
|
||||||
|
));
|
||||||
|
$names=array();
|
||||||
|
foreach($tags as $tag)
|
||||||
|
$names[]=$tag->name;
|
||||||
|
return $names;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function string2array($tags)
|
||||||
|
{
|
||||||
|
return preg_split('/\s*,\s*/',trim($tags),-1,PREG_SPLIT_NO_EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function array2string($tags)
|
||||||
|
{
|
||||||
|
return implode(', ',$tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateFrequency($oldTags, $newTags)
|
||||||
|
{
|
||||||
|
$oldTags=self::string2array($oldTags);
|
||||||
|
$newTags=self::string2array($newTags);
|
||||||
|
$this->addTags(array_values(array_diff($newTags,$oldTags)));
|
||||||
|
$this->removeTags(array_values(array_diff($oldTags,$newTags)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addTags($tags)
|
||||||
|
{
|
||||||
|
$criteria=new CDbCriteria;
|
||||||
|
$criteria->addInCondition('name',$tags);
|
||||||
|
$this->updateCounters(array('frequency'=>1),$criteria);
|
||||||
|
foreach($tags as $name)
|
||||||
|
{
|
||||||
|
if(!$this->exists('name=:name',array(':name'=>$name)))
|
||||||
|
{
|
||||||
|
$tag=new Tag;
|
||||||
|
$tag->name=$name;
|
||||||
|
$tag->frequency=1;
|
||||||
|
$tag->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeTags($tags)
|
||||||
|
{
|
||||||
|
if(empty($tags))
|
||||||
|
return;
|
||||||
|
$criteria=new CDbCriteria;
|
||||||
|
$criteria->addInCondition('name',$tags);
|
||||||
|
$this->updateCounters(array('frequency'=>-1),$criteria);
|
||||||
|
$this->deleteAll('frequency<=0');
|
||||||
|
}
|
||||||
|
}
|
90
demos/blog/protected/models/User.php
Normal file
90
demos/blog/protected/models/User.php
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class User extends CActiveRecord
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The followings are the available columns in table 'tbl_user':
|
||||||
|
* @var integer $id
|
||||||
|
* @var string $username
|
||||||
|
* @var string $password
|
||||||
|
* @var string $email
|
||||||
|
* @var string $profile
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the static model of the specified AR class.
|
||||||
|
* @return CActiveRecord the static model class
|
||||||
|
*/
|
||||||
|
public static function model($className=__CLASS__)
|
||||||
|
{
|
||||||
|
return parent::model($className);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string the associated database table name
|
||||||
|
*/
|
||||||
|
public function tableName()
|
||||||
|
{
|
||||||
|
return '{{user}}';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array validation rules for model attributes.
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
// NOTE: you should only define rules for those attributes that
|
||||||
|
// will receive user inputs.
|
||||||
|
return array(
|
||||||
|
array('username, password, email', 'required'),
|
||||||
|
array('username, password, email', 'length', 'max'=>128),
|
||||||
|
array('profile', 'safe'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array relational rules.
|
||||||
|
*/
|
||||||
|
public function relations()
|
||||||
|
{
|
||||||
|
// NOTE: you may need to adjust the relation name and the related
|
||||||
|
// class name for the relations automatically generated below.
|
||||||
|
return array(
|
||||||
|
'posts' => array(self::HAS_MANY, 'Post', 'author_id'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array customized attribute labels (name=>label)
|
||||||
|
*/
|
||||||
|
public function attributeLabels()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'id' => 'Id',
|
||||||
|
'username' => 'Username',
|
||||||
|
'password' => 'Password',
|
||||||
|
'email' => 'Email',
|
||||||
|
'profile' => 'Profile',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given password is correct.
|
||||||
|
* @param string the password to be validated
|
||||||
|
* @return boolean whether the password is valid
|
||||||
|
*/
|
||||||
|
public function validatePassword($password)
|
||||||
|
{
|
||||||
|
return CPasswordHelper::verifyPassword($password,$this->password);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the password hash.
|
||||||
|
* @param string password
|
||||||
|
* @return string hash
|
||||||
|
*/
|
||||||
|
public function hashPassword($password)
|
||||||
|
{
|
||||||
|
return CPasswordHelper::hashPassword($password);
|
||||||
|
}
|
||||||
|
}
|
25
demos/blog/protected/tests/WebTestCase.php
Normal file
25
demos/blog/protected/tests/WebTestCase.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the following URL based on your server configuration
|
||||||
|
* Make sure the URL ends with a slash so that we can use relative URLs in test cases
|
||||||
|
*/
|
||||||
|
define('TEST_BASE_URL','http://localhost/yii/demos/blog/index-test.php/');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base class for functional test cases.
|
||||||
|
* In this class, we set the base URL for the test application.
|
||||||
|
* We also provide some common methods to be used by concrete test classes.
|
||||||
|
*/
|
||||||
|
class WebTestCase extends CWebTestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Sets up before each test method runs.
|
||||||
|
* This mainly sets the base URL for the test application.
|
||||||
|
*/
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
$this->setBrowserUrl(TEST_BASE_URL);
|
||||||
|
}
|
||||||
|
}
|
10
demos/blog/protected/tests/bootstrap.php
Normal file
10
demos/blog/protected/tests/bootstrap.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// change the following paths if necessary
|
||||||
|
$yiit=dirname(__FILE__).'/../../../../framework/yiit.php';
|
||||||
|
$config=dirname(__FILE__).'/../config/test.php';
|
||||||
|
|
||||||
|
require_once($yiit);
|
||||||
|
require_once(dirname(__FILE__).'/WebTestCase.php');
|
||||||
|
|
||||||
|
Yii::createWebApplication($config);
|
24
demos/blog/protected/tests/fixtures/tbl_comment.php
vendored
Normal file
24
demos/blog/protected/tests/fixtures/tbl_comment.php
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
/*
|
||||||
|
'sample1'=>array(
|
||||||
|
'content' => '',
|
||||||
|
'status' => '',
|
||||||
|
'create_time' => '',
|
||||||
|
'author' => '',
|
||||||
|
'email' => '',
|
||||||
|
'url' => '',
|
||||||
|
'post_id' => '',
|
||||||
|
),
|
||||||
|
'sample2'=>array(
|
||||||
|
'content' => '',
|
||||||
|
'status' => '',
|
||||||
|
'create_time' => '',
|
||||||
|
'author' => '',
|
||||||
|
'email' => '',
|
||||||
|
'url' => '',
|
||||||
|
'post_id' => '',
|
||||||
|
),
|
||||||
|
*/
|
||||||
|
);
|
18
demos/blog/protected/tests/fixtures/tbl_lookup.php
vendored
Normal file
18
demos/blog/protected/tests/fixtures/tbl_lookup.php
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
/*
|
||||||
|
'sample1'=>array(
|
||||||
|
'name' => '',
|
||||||
|
'code' => '',
|
||||||
|
'type' => '',
|
||||||
|
'position' => '',
|
||||||
|
),
|
||||||
|
'sample2'=>array(
|
||||||
|
'name' => '',
|
||||||
|
'code' => '',
|
||||||
|
'type' => '',
|
||||||
|
'position' => '',
|
||||||
|
),
|
||||||
|
*/
|
||||||
|
);
|
13
demos/blog/protected/tests/fixtures/tbl_post.php
vendored
Normal file
13
demos/blog/protected/tests/fixtures/tbl_post.php
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'sample1'=>array(
|
||||||
|
'title'=>'test post 1',
|
||||||
|
'content'=>"This blog is powered by [Yii framework](http://www.yiiframework.com).",
|
||||||
|
'status'=>2,
|
||||||
|
'create_time'=>1230952187,
|
||||||
|
'update_time'=>1230952187,
|
||||||
|
'author_id'=>1,
|
||||||
|
'tags'=>'yii, blog',
|
||||||
|
),
|
||||||
|
);
|
12
demos/blog/protected/tests/fixtures/tbl_tag.php
vendored
Normal file
12
demos/blog/protected/tests/fixtures/tbl_tag.php
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
array(
|
||||||
|
'name'=>'yii',
|
||||||
|
'frequency'=>1,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'name'=>'blog',
|
||||||
|
'frequency'=>1,
|
||||||
|
),
|
||||||
|
);
|
9
demos/blog/protected/tests/fixtures/tbl_user.php
vendored
Normal file
9
demos/blog/protected/tests/fixtures/tbl_user.php
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
array(
|
||||||
|
'username'=>'demo',
|
||||||
|
'password'=>'$2a$10$JTJf6/XqC94rrOtzuF397OHa4mbmZrVTBOQCmYD9U.obZRUut4BoC',
|
||||||
|
'email'=>'webmaster@example.com',
|
||||||
|
),
|
||||||
|
);
|
36
demos/blog/protected/tests/functional/CommentTest.php
Normal file
36
demos/blog/protected/tests/functional/CommentTest.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class CommentTest extends WebTestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* We use both 'Post' and 'Comment' fixtures.
|
||||||
|
* @see CWebTestCase::fixtures
|
||||||
|
*/
|
||||||
|
public $fixtures=array(
|
||||||
|
'posts'=>'Post',
|
||||||
|
'comments'=>'Comment',
|
||||||
|
);
|
||||||
|
|
||||||
|
public function testCreate()
|
||||||
|
{
|
||||||
|
$this->open('post/1/xyz');
|
||||||
|
|
||||||
|
// verify the sample post title exists
|
||||||
|
$this->assertTextPresent($this->posts['sample1']['title']);
|
||||||
|
$this->assertElementPresent("name=Comment[author]");
|
||||||
|
|
||||||
|
// verify validation errors
|
||||||
|
$this->clickAndWait("//input[@value='Submit']");
|
||||||
|
$this->assertTextPresent('Name cannot be blank.');
|
||||||
|
$this->assertTextPresent('Email cannot be blank.');
|
||||||
|
$this->assertTextPresent('Comment cannot be blank.');
|
||||||
|
|
||||||
|
// verify commenting is successful
|
||||||
|
$comment="comment 1";
|
||||||
|
$this->type('name=Comment[author]','me');
|
||||||
|
$this->type('name=Comment[email]','me@example.com');
|
||||||
|
$this->type('name=Comment[content]',$comment);
|
||||||
|
$this->clickAndWait("//input[@value='Submit']");
|
||||||
|
$this->assertTextPresent('Thank you for your comment');
|
||||||
|
}
|
||||||
|
}
|
30
demos/blog/protected/tests/functional/PostTest.php
Normal file
30
demos/blog/protected/tests/functional/PostTest.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class PostTest extends WebTestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* We use the 'Post' only for this test.
|
||||||
|
* @see CWebTestCase::fixtures
|
||||||
|
*/
|
||||||
|
public $fixtures=array(
|
||||||
|
'posts'=>'Post',
|
||||||
|
);
|
||||||
|
|
||||||
|
public function testIndex()
|
||||||
|
{
|
||||||
|
$this->open('');
|
||||||
|
// verify header title exists
|
||||||
|
$this->assertTextPresent('Yii Blog Demo');
|
||||||
|
// verify the sample post title exists
|
||||||
|
$this->assertTextPresent($this->posts['sample1']['title']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testView()
|
||||||
|
{
|
||||||
|
$this->open('post/1/xyz');
|
||||||
|
// verify the sample post title exists
|
||||||
|
$this->assertTextPresent($this->posts['sample1']['title']);
|
||||||
|
// verify comment form exists
|
||||||
|
$this->assertTextPresent('Leave a Comment');
|
||||||
|
}
|
||||||
|
}
|
41
demos/blog/protected/tests/functional/SiteTest.php
Normal file
41
demos/blog/protected/tests/functional/SiteTest.php
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class SiteTest extends WebTestCase
|
||||||
|
{
|
||||||
|
public function testContact()
|
||||||
|
{
|
||||||
|
$this->open('site/contact');
|
||||||
|
$this->assertTextPresent('Contact Us');
|
||||||
|
$this->assertElementPresent('name=ContactForm[name]');
|
||||||
|
|
||||||
|
$this->type('name=ContactForm[name]','tester');
|
||||||
|
$this->type('name=ContactForm[email]','tester@example.com');
|
||||||
|
$this->type('name=ContactForm[subject]','test subject');
|
||||||
|
$this->clickAndWait("//input[@value='Submit']");
|
||||||
|
$this->assertTextPresent('Body cannot be blank.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLoginLogout()
|
||||||
|
{
|
||||||
|
$this->open('');
|
||||||
|
// ensure the user is logged out
|
||||||
|
if($this->isTextPresent('Logout'))
|
||||||
|
$this->clickAndWait('link=Logout');
|
||||||
|
|
||||||
|
// test login process, including validation
|
||||||
|
$this->clickAndWait('link=Login');
|
||||||
|
$this->assertElementPresent('name=LoginForm[username]');
|
||||||
|
$this->type('name=LoginForm[username]','demo');
|
||||||
|
$this->clickAndWait("//input[@value='Login']");
|
||||||
|
$this->assertTextPresent('Password cannot be blank.');
|
||||||
|
$this->type('name=LoginForm[password]','demo');
|
||||||
|
$this->clickAndWait("//input[@value='Login']");
|
||||||
|
$this->assertTextNotPresent('Password cannot be blank.');
|
||||||
|
$this->assertTextPresent('Logout');
|
||||||
|
|
||||||
|
// test logout process
|
||||||
|
$this->assertTextNotPresent('Login');
|
||||||
|
$this->clickAndWait('link=Logout');
|
||||||
|
$this->assertTextPresent('Login');
|
||||||
|
}
|
||||||
|
}
|
13
demos/blog/protected/tests/phpunit.xml
Normal file
13
demos/blog/protected/tests/phpunit.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<phpunit bootstrap="bootstrap.php"
|
||||||
|
colors="false"
|
||||||
|
convertErrorsToExceptions="true"
|
||||||
|
convertNoticesToExceptions="true"
|
||||||
|
convertWarningsToExceptions="true"
|
||||||
|
stopOnFailure="false">
|
||||||
|
|
||||||
|
<selenium>
|
||||||
|
<browser name="Internet Explorer" browser="*iexplore" />
|
||||||
|
<browser name="Firefox" browser="*firefox" />
|
||||||
|
</selenium>
|
||||||
|
|
||||||
|
</phpunit>
|
42
demos/blog/protected/tests/readme.txt
Normal file
42
demos/blog/protected/tests/readme.txt
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
This directory contains unit and functional tests for the blog demo.
|
||||||
|
|
||||||
|
- fixtures: contains fixture data for relevant database tables.
|
||||||
|
Each file is used to set up the fixture data for a particular table.
|
||||||
|
The file name is the same as the table name.
|
||||||
|
|
||||||
|
- functional: contains functional test cases.
|
||||||
|
|
||||||
|
- unit: contains unit test cases.
|
||||||
|
|
||||||
|
- report: contains any coverage reports.
|
||||||
|
|
||||||
|
|
||||||
|
In order to run these tests, the following requirements must be met:
|
||||||
|
|
||||||
|
- PHPUnit 3.3 or higher
|
||||||
|
- Selenium RC 1.0 or higher
|
||||||
|
|
||||||
|
|
||||||
|
Depending on your installation of Yii release, you may need to modify
|
||||||
|
the file "WebTestCase.php" so that the "TEST_BASE_URL" constant contains
|
||||||
|
correct value. You may also modify "phpunit.xml" to specify the browsers
|
||||||
|
you intend to run the functional tests on.
|
||||||
|
|
||||||
|
To run these tests, please refer to PHPUnit documentation. The followings
|
||||||
|
are some examples:
|
||||||
|
|
||||||
|
- Executes all tests under the "unit" directory with verbose information:
|
||||||
|
|
||||||
|
phpunit --verbose unit
|
||||||
|
|
||||||
|
- Executes all tests under "functional" (Selenium RC is running):
|
||||||
|
|
||||||
|
phpunit functional
|
||||||
|
|
||||||
|
- Executes a particular test:
|
||||||
|
|
||||||
|
phpunit functional/PostTest.php
|
||||||
|
|
||||||
|
|
||||||
|
*DISCLAIMER* The test cases included here are by no means complete. They mainly serve
|
||||||
|
for demonstrative purpose.
|
57
demos/blog/protected/tests/unit/CommentTest.php
Normal file
57
demos/blog/protected/tests/unit/CommentTest.php
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class CommentTest extends CDbTestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* We use both 'Post' and 'Comment' fixtures.
|
||||||
|
* @see CWebTestCase::fixtures
|
||||||
|
*/
|
||||||
|
public $fixtures=array(
|
||||||
|
'posts'=>'Post',
|
||||||
|
'comments'=>'Comment',
|
||||||
|
);
|
||||||
|
|
||||||
|
public function testFindRecentComments()
|
||||||
|
{
|
||||||
|
$this->assertEquals(array(), Comment::model()->findRecentComments());
|
||||||
|
|
||||||
|
$comment=new Comment;
|
||||||
|
$comment->setAttributes(array(
|
||||||
|
'content'=>'comment 1',
|
||||||
|
'status'=>Comment::STATUS_APPROVED,
|
||||||
|
'create_time'=>time(),
|
||||||
|
'author'=>'me',
|
||||||
|
'email'=>'me@example.com',
|
||||||
|
'post_id'=>$this->posts['sample1']['id'],
|
||||||
|
),false);
|
||||||
|
$this->assertTrue($comment->save(false));
|
||||||
|
$this->assertEquals(1,$comment->id);
|
||||||
|
|
||||||
|
$comments=Comment::model()->findRecentComments();
|
||||||
|
$this->assertEquals(1,count($comments));
|
||||||
|
$this->assertEquals($comment->attributes, $comments[0]->attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testApprove()
|
||||||
|
{
|
||||||
|
$comment=new Comment;
|
||||||
|
$comment->setAttributes(array(
|
||||||
|
'content'=>'comment 1',
|
||||||
|
'status'=>Comment::STATUS_PENDING,
|
||||||
|
'create_time'=>time(),
|
||||||
|
'author'=>'me',
|
||||||
|
'email'=>'me@example.com',
|
||||||
|
'post_id'=>$this->posts['sample1']['id'],
|
||||||
|
),false);
|
||||||
|
$this->assertTrue($comment->save(false));
|
||||||
|
|
||||||
|
$comment=Comment::model()->findByPk($comment->id);
|
||||||
|
$this->assertTrue($comment instanceof Comment);
|
||||||
|
$this->assertEquals(Comment::STATUS_PENDING,$comment->status);
|
||||||
|
|
||||||
|
$comment->approve();
|
||||||
|
$this->assertEquals(Comment::STATUS_APPROVED,$comment->status);
|
||||||
|
$comment=Comment::model()->findByPk($comment->id);
|
||||||
|
$this->assertEquals(Comment::STATUS_APPROVED,$comment->status);
|
||||||
|
}
|
||||||
|
}
|
13
demos/blog/protected/tests/unit/LookupTest.php
Normal file
13
demos/blog/protected/tests/unit/LookupTest.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class LookupTest extends CDbTestCase
|
||||||
|
{
|
||||||
|
public $fixtures=array(
|
||||||
|
'lookups'=>'Lookup',
|
||||||
|
);
|
||||||
|
|
||||||
|
public function testCreate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
18
demos/blog/protected/tests/unit/PostTest.php
Normal file
18
demos/blog/protected/tests/unit/PostTest.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class PostTest extends CDbTestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* We use both 'Post' and 'Comment' fixtures.
|
||||||
|
* @see CWebTestCase::fixtures
|
||||||
|
*/
|
||||||
|
public $fixtures=array(
|
||||||
|
'posts'=>'Post',
|
||||||
|
'comments'=>'Comment',
|
||||||
|
);
|
||||||
|
|
||||||
|
public function testSave()
|
||||||
|
{
|
||||||
|
// write code here to test post saving method
|
||||||
|
}
|
||||||
|
}
|
13
demos/blog/protected/tests/unit/TagTest.php
Normal file
13
demos/blog/protected/tests/unit/TagTest.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class TagTest extends CDbTestCase
|
||||||
|
{
|
||||||
|
public $fixtures=array(
|
||||||
|
'tags'=>'Tag',
|
||||||
|
);
|
||||||
|
|
||||||
|
public function testCreate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
24
demos/blog/protected/tests/unit/UserTest.php
Normal file
24
demos/blog/protected/tests/unit/UserTest.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class UserTest extends CDbTestCase
|
||||||
|
{
|
||||||
|
public $fixtures=array(
|
||||||
|
'users'=>'User',
|
||||||
|
);
|
||||||
|
|
||||||
|
public function testValidatePassword()
|
||||||
|
{
|
||||||
|
$this->assertTrue($this->users(0)->validatePassword('demo'));
|
||||||
|
$this->assertFalse($this->users(0)->validatePassword('wrong'));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testChangePassword()
|
||||||
|
{
|
||||||
|
$user=$this->users(0);
|
||||||
|
$user->password=$user->hashPassword('newpwd');
|
||||||
|
$this->assertFalse($user->validatePassword('demo'));
|
||||||
|
$this->assertTrue($user->validatePassword('newpwd'));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
40
demos/blog/protected/views/comment/_form.php
Normal file
40
demos/blog/protected/views/comment/_form.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<div class="form">
|
||||||
|
|
||||||
|
<?php $form=$this->beginWidget('CActiveForm', array(
|
||||||
|
'id'=>'comment-form',
|
||||||
|
'enableAjaxValidation'=>true,
|
||||||
|
)); ?>
|
||||||
|
|
||||||
|
<p class="note">Fields with <span class="required">*</span> are required.</p>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<?php echo $form->labelEx($model,'author'); ?>
|
||||||
|
<?php echo $form->textField($model,'author',array('size'=>60,'maxlength'=>128)); ?>
|
||||||
|
<?php echo $form->error($model,'author'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<?php echo $form->labelEx($model,'email'); ?>
|
||||||
|
<?php echo $form->textField($model,'email',array('size'=>60,'maxlength'=>128)); ?>
|
||||||
|
<?php echo $form->error($model,'email'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<?php echo $form->labelEx($model,'url'); ?>
|
||||||
|
<?php echo $form->textField($model,'url',array('size'=>60,'maxlength'=>128)); ?>
|
||||||
|
<?php echo $form->error($model,'url'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<?php echo $form->labelEx($model,'content'); ?>
|
||||||
|
<?php echo $form->textArea($model,'content',array('rows'=>6, 'cols'=>50)); ?>
|
||||||
|
<?php echo $form->error($model,'content'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row buttons">
|
||||||
|
<?php echo CHtml::submitButton($model->isNewRecord ? 'Submit' : 'Save'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php $this->endWidget(); ?>
|
||||||
|
|
||||||
|
</div><!-- form -->
|
46
demos/blog/protected/views/comment/_view.php
Normal file
46
demos/blog/protected/views/comment/_view.php
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
$deleteJS = <<<DEL
|
||||||
|
$('.container').on('click','.time a.delete',function() {
|
||||||
|
var th=$(this),
|
||||||
|
container=th.closest('div.comment'),
|
||||||
|
id=container.attr('id').slice(1);
|
||||||
|
if(confirm('Are you sure you want to delete comment #'+id+'?')) {
|
||||||
|
$.ajax({
|
||||||
|
url:th.attr('href'),
|
||||||
|
type:'POST'
|
||||||
|
}).done(function(){container.slideUp()});
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
DEL;
|
||||||
|
Yii::app()->getClientScript()->registerScript('delete', $deleteJS);
|
||||||
|
?>
|
||||||
|
<div class="comment" id="c<?php echo $data->id; ?>">
|
||||||
|
|
||||||
|
<?php echo CHtml::link("#{$data->id}", $data->url, array(
|
||||||
|
'class'=>'cid',
|
||||||
|
'title'=>'Permalink to this comment',
|
||||||
|
)); ?>
|
||||||
|
|
||||||
|
<div class="author">
|
||||||
|
<?php echo $data->authorLink; ?> says on
|
||||||
|
<?php echo CHtml::link(CHtml::encode($data->post->title), $data->post->url); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="time">
|
||||||
|
<?php if($data->status==Comment::STATUS_PENDING): ?>
|
||||||
|
<span class="pending">Pending approval</span> |
|
||||||
|
<?php echo CHtml::linkButton('Approve', array(
|
||||||
|
'submit'=>array('comment/approve','id'=>$data->id),
|
||||||
|
)); ?> |
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php echo CHtml::link('Update',array('comment/update','id'=>$data->id)); ?> |
|
||||||
|
<?php echo CHtml::link('Delete',array('comment/delete','id'=>$data->id),array('class'=>'delete')); ?> |
|
||||||
|
<?php echo date('F j, Y \a\t h:i a',$data->create_time); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<?php echo nl2br(CHtml::encode($data->content)); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div><!-- comment -->
|
12
demos/blog/protected/views/comment/index.php
Normal file
12
demos/blog/protected/views/comment/index.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
$this->breadcrumbs=array(
|
||||||
|
'Comments',
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h1>Comments</h1>
|
||||||
|
|
||||||
|
<?php $this->widget('zii.widgets.CListView', array(
|
||||||
|
'dataProvider'=>$dataProvider,
|
||||||
|
'itemView'=>'_view',
|
||||||
|
)); ?>
|
10
demos/blog/protected/views/comment/update.php
Normal file
10
demos/blog/protected/views/comment/update.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
$this->breadcrumbs=array(
|
||||||
|
'Comments'=>array('index'),
|
||||||
|
'Update Comment #'.$model->id,
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h1>Update Comment #<?php echo $model->id; ?></h1>
|
||||||
|
|
||||||
|
<?php echo $this->renderPartial('_form', array('model'=>$model)); ?>
|
7
demos/blog/protected/views/layouts/column1.php
Normal file
7
demos/blog/protected/views/layouts/column1.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php $this->beginContent('/layouts/main'); ?>
|
||||||
|
<div class="container">
|
||||||
|
<div id="content">
|
||||||
|
<?php echo $content; ?>
|
||||||
|
</div><!-- content -->
|
||||||
|
</div>
|
||||||
|
<?php $this->endContent(); ?>
|
22
demos/blog/protected/views/layouts/column2.php
Normal file
22
demos/blog/protected/views/layouts/column2.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php $this->beginContent('/layouts/main'); ?>
|
||||||
|
<div class="container">
|
||||||
|
<div class="span-18">
|
||||||
|
<div id="content">
|
||||||
|
<?php echo $content; ?>
|
||||||
|
</div><!-- content -->
|
||||||
|
</div>
|
||||||
|
<div class="span-6 last">
|
||||||
|
<div id="sidebar">
|
||||||
|
<?php if(!Yii::app()->user->isGuest) $this->widget('UserMenu'); ?>
|
||||||
|
|
||||||
|
<?php $this->widget('TagCloud', array(
|
||||||
|
'maxTags'=>Yii::app()->params['tagCloudCount'],
|
||||||
|
)); ?>
|
||||||
|
|
||||||
|
<?php $this->widget('RecentComments', array(
|
||||||
|
'maxComments'=>Yii::app()->params['recentCommentCount'],
|
||||||
|
)); ?>
|
||||||
|
</div><!-- sidebar -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php $this->endContent(); ?>
|
55
demos/blog/protected/views/layouts/main.php
Normal file
55
demos/blog/protected/views/layouts/main.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<meta name="language" content="en" />
|
||||||
|
|
||||||
|
<!-- blueprint CSS framework -->
|
||||||
|
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/screen.css" media="screen, projection" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/print.css" media="print" />
|
||||||
|
<!--[if lt IE 8]>
|
||||||
|
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/ie.css" media="screen, projection" />
|
||||||
|
<![endif]-->
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/main.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/form.css" />
|
||||||
|
|
||||||
|
<title><?php echo CHtml::encode($this->pageTitle); ?></title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="container" id="page">
|
||||||
|
|
||||||
|
<div id="header">
|
||||||
|
<div id="logo"><?php echo CHtml::encode(Yii::app()->name); ?></div>
|
||||||
|
</div><!-- header -->
|
||||||
|
|
||||||
|
<div id="mainmenu">
|
||||||
|
<?php $this->widget('zii.widgets.CMenu',array(
|
||||||
|
'items'=>array(
|
||||||
|
array('label'=>'Home', 'url'=>array('post/index')),
|
||||||
|
array('label'=>'About', 'url'=>array('site/page', 'view'=>'about')),
|
||||||
|
array('label'=>'Contact', 'url'=>array('site/contact')),
|
||||||
|
array('label'=>'Login', 'url'=>array('site/login'), 'visible'=>Yii::app()->user->isGuest),
|
||||||
|
array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('site/logout'), 'visible'=>!Yii::app()->user->isGuest)
|
||||||
|
),
|
||||||
|
)); ?>
|
||||||
|
</div><!-- mainmenu -->
|
||||||
|
|
||||||
|
<?php $this->widget('zii.widgets.CBreadcrumbs', array(
|
||||||
|
'links'=>$this->breadcrumbs,
|
||||||
|
)); ?><!-- breadcrumbs -->
|
||||||
|
|
||||||
|
<?php echo $content; ?>
|
||||||
|
|
||||||
|
<div id="footer">
|
||||||
|
Copyright © <?php echo date('Y'); ?> by My Company.<br/>
|
||||||
|
All Rights Reserved.<br/>
|
||||||
|
<?php echo Yii::powered(); ?>
|
||||||
|
</div><!-- footer -->
|
||||||
|
|
||||||
|
</div><!-- page -->
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
22
demos/blog/protected/views/post/_comments.php
Normal file
22
demos/blog/protected/views/post/_comments.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php foreach($comments as $comment): ?>
|
||||||
|
<div class="comment" id="c<?php echo $comment->id; ?>">
|
||||||
|
|
||||||
|
<?php echo CHtml::link("#{$comment->id}", $comment->getUrl($post), array(
|
||||||
|
'class'=>'cid',
|
||||||
|
'title'=>'Permalink to this comment',
|
||||||
|
)); ?>
|
||||||
|
|
||||||
|
<div class="author">
|
||||||
|
<?php echo $comment->authorLink; ?> says:
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="time">
|
||||||
|
<?php echo date('F j, Y \a\t h:i a',$comment->create_time); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<?php echo nl2br(CHtml::encode($comment->content)); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div><!-- comment -->
|
||||||
|
<?php endforeach; ?>
|
47
demos/blog/protected/views/post/_form.php
Normal file
47
demos/blog/protected/views/post/_form.php
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<div class="form">
|
||||||
|
|
||||||
|
<?php $form=$this->beginWidget('CActiveForm'); ?>
|
||||||
|
|
||||||
|
<p class="note">Fields with <span class="required">*</span> are required.</p>
|
||||||
|
|
||||||
|
<?php echo CHtml::errorSummary($model); ?>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<?php echo $form->labelEx($model,'title'); ?>
|
||||||
|
<?php echo $form->textField($model,'title',array('size'=>80,'maxlength'=>128)); ?>
|
||||||
|
<?php echo $form->error($model,'title'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<?php echo $form->labelEx($model,'content'); ?>
|
||||||
|
<?php echo CHtml::activeTextArea($model,'content',array('rows'=>10, 'cols'=>70)); ?>
|
||||||
|
<p class="hint">You may use <a target="_blank" href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a>.</p>
|
||||||
|
<?php echo $form->error($model,'content'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<?php echo $form->labelEx($model,'tags'); ?>
|
||||||
|
<?php $this->widget('CAutoComplete', array(
|
||||||
|
'model'=>$model,
|
||||||
|
'attribute'=>'tags',
|
||||||
|
'url'=>array('suggestTags'),
|
||||||
|
'multiple'=>true,
|
||||||
|
'htmlOptions'=>array('size'=>50),
|
||||||
|
)); ?>
|
||||||
|
<p class="hint">Please separate different tags with commas.</p>
|
||||||
|
<?php echo $form->error($model,'tags'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<?php echo $form->labelEx($model,'status'); ?>
|
||||||
|
<?php echo $form->dropDownList($model,'status',Lookup::items('PostStatus')); ?>
|
||||||
|
<?php echo $form->error($model,'status'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row buttons">
|
||||||
|
<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php $this->endWidget(); ?>
|
||||||
|
|
||||||
|
</div><!-- form -->
|
23
demos/blog/protected/views/post/_view.php
Normal file
23
demos/blog/protected/views/post/_view.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<div class="post">
|
||||||
|
<div class="title">
|
||||||
|
<?php echo CHtml::link(CHtml::encode($data->title), $data->url); ?>
|
||||||
|
</div>
|
||||||
|
<div class="author">
|
||||||
|
posted by <?php echo $data->author->username . ' on ' . date('F j, Y',$data->create_time); ?>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<?php
|
||||||
|
$this->beginWidget('CMarkdown', array('purifyOutput'=>true));
|
||||||
|
echo $data->content;
|
||||||
|
$this->endWidget();
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<div class="nav">
|
||||||
|
<b>Tags:</b>
|
||||||
|
<?php echo implode(', ', $data->tagLinks); ?>
|
||||||
|
<br/>
|
||||||
|
<?php echo CHtml::link('Permalink', $data->url); ?> |
|
||||||
|
<?php echo CHtml::link("Comments ({$data->commentCount})",$data->url.'#comments'); ?> |
|
||||||
|
Last updated on <?php echo date('F j, Y',$data->update_time); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
31
demos/blog/protected/views/post/admin.php
Normal file
31
demos/blog/protected/views/post/admin.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
$this->breadcrumbs=array(
|
||||||
|
'Manage Posts',
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
<h1>Manage Posts</h1>
|
||||||
|
|
||||||
|
<?php $this->widget('zii.widgets.grid.CGridView', array(
|
||||||
|
'dataProvider'=>$model->search(),
|
||||||
|
'filter'=>$model,
|
||||||
|
'columns'=>array(
|
||||||
|
array(
|
||||||
|
'name'=>'title',
|
||||||
|
'type'=>'raw',
|
||||||
|
'value'=>'CHtml::link(CHtml::encode($data->title), $data->url)'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'name'=>'status',
|
||||||
|
'value'=>'Lookup::item("PostStatus",$data->status)',
|
||||||
|
'filter'=>Lookup::items('PostStatus'),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'name'=>'create_time',
|
||||||
|
'type'=>'datetime',
|
||||||
|
'filter'=>false,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'class'=>'CButtonColumn',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)); ?>
|
8
demos/blog/protected/views/post/create.php
Normal file
8
demos/blog/protected/views/post/create.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
$this->breadcrumbs=array(
|
||||||
|
'Create Post',
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
<h1>Create Post</h1>
|
||||||
|
|
||||||
|
<?php echo $this->renderPartial('_form', array('model'=>$model)); ?>
|
9
demos/blog/protected/views/post/index.php
Normal file
9
demos/blog/protected/views/post/index.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php if(!empty($_GET['tag'])): ?>
|
||||||
|
<h1>Posts Tagged with <i><?php echo CHtml::encode($_GET['tag']); ?></i></h1>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php $this->widget('zii.widgets.CListView', array(
|
||||||
|
'dataProvider'=>$dataProvider,
|
||||||
|
'itemView'=>'_view',
|
||||||
|
'template'=>"{items}\n{pager}",
|
||||||
|
)); ?>
|
10
demos/blog/protected/views/post/update.php
Normal file
10
demos/blog/protected/views/post/update.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
$this->breadcrumbs=array(
|
||||||
|
$model->title=>$model->url,
|
||||||
|
'Update',
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h1>Update <i><?php echo CHtml::encode($model->title); ?></i></h1>
|
||||||
|
|
||||||
|
<?php echo $this->renderPartial('_form', array('model'=>$model)); ?>
|
36
demos/blog/protected/views/post/view.php
Normal file
36
demos/blog/protected/views/post/view.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
$this->breadcrumbs=array(
|
||||||
|
$model->title,
|
||||||
|
);
|
||||||
|
$this->pageTitle=$model->title;
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php $this->renderPartial('_view', array(
|
||||||
|
'data'=>$model,
|
||||||
|
)); ?>
|
||||||
|
|
||||||
|
<div id="comments">
|
||||||
|
<?php if($model->commentCount>=1): ?>
|
||||||
|
<h3>
|
||||||
|
<?php echo $model->commentCount>1 ? $model->commentCount . ' comments' : 'One comment'; ?>
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<?php $this->renderPartial('_comments',array(
|
||||||
|
'post'=>$model,
|
||||||
|
'comments'=>$model->comments,
|
||||||
|
)); ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<h3>Leave a Comment</h3>
|
||||||
|
|
||||||
|
<?php if(Yii::app()->user->hasFlash('commentSubmitted')): ?>
|
||||||
|
<div class="flash-success">
|
||||||
|
<?php echo Yii::app()->user->getFlash('commentSubmitted'); ?>
|
||||||
|
</div>
|
||||||
|
<?php else: ?>
|
||||||
|
<?php $this->renderPartial('/comment/_form',array(
|
||||||
|
'model'=>$comment,
|
||||||
|
)); ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
</div><!-- comments -->
|
70
demos/blog/protected/views/site/contact.php
Normal file
70
demos/blog/protected/views/site/contact.php
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
$this->pageTitle=Yii::app()->name . ' - Contact Us';
|
||||||
|
$this->breadcrumbs=array(
|
||||||
|
'Contact',
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h1>Contact Us</h1>
|
||||||
|
|
||||||
|
<?php if(Yii::app()->user->hasFlash('contact')): ?>
|
||||||
|
|
||||||
|
<div class="flash-success">
|
||||||
|
<?php echo Yii::app()->user->getFlash('contact'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php else: ?>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If you have business inquiries or other questions, please fill out the following form to contact us. Thank you.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="form">
|
||||||
|
|
||||||
|
<?php $form=$this->beginWidget('CActiveForm'); ?>
|
||||||
|
|
||||||
|
<p class="note">Fields with <span class="required">*</span> are required.</p>
|
||||||
|
|
||||||
|
<?php echo $form->errorSummary($model); ?>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<?php echo $form->labelEx($model,'name'); ?>
|
||||||
|
<?php echo $form->textField($model,'name'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<?php echo $form->labelEx($model,'email'); ?>
|
||||||
|
<?php echo $form->textField($model,'email'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<?php echo $form->labelEx($model,'subject'); ?>
|
||||||
|
<?php echo $form->textField($model,'subject',array('size'=>60,'maxlength'=>128)); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<?php echo $form->labelEx($model,'body'); ?>
|
||||||
|
<?php echo $form->textArea($model,'body',array('rows'=>6, 'cols'=>50)); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if(CCaptcha::checkRequirements()): ?>
|
||||||
|
<div class="row">
|
||||||
|
<?php echo $form->labelEx($model,'verifyCode'); ?>
|
||||||
|
<div>
|
||||||
|
<?php $this->widget('CCaptcha'); ?>
|
||||||
|
<?php echo $form->textField($model,'verifyCode'); ?>
|
||||||
|
</div>
|
||||||
|
<div class="hint">Please enter the letters as they are shown in the image above.
|
||||||
|
<br/>Letters are not case-sensitive.</div>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="row submit">
|
||||||
|
<?php echo CHtml::submitButton('Submit'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php $this->endWidget(); ?>
|
||||||
|
|
||||||
|
</div><!-- form -->
|
||||||
|
|
||||||
|
<?php endif; ?>
|
12
demos/blog/protected/views/site/error.php
Normal file
12
demos/blog/protected/views/site/error.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
$this->pageTitle=Yii::app()->name . ' - Error';
|
||||||
|
$this->breadcrumbs=array(
|
||||||
|
'Error',
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h2>Error <?php echo $code; ?></h2>
|
||||||
|
|
||||||
|
<div class="error">
|
||||||
|
<?php echo CHtml::encode($message); ?>
|
||||||
|
</div>
|
46
demos/blog/protected/views/site/login.php
Normal file
46
demos/blog/protected/views/site/login.php
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
$this->pageTitle=Yii::app()->name . ' - Login';
|
||||||
|
$this->breadcrumbs=array(
|
||||||
|
'Login',
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h1>Login</h1>
|
||||||
|
|
||||||
|
<p>Please fill out the following form with your login credentials:</p>
|
||||||
|
|
||||||
|
<div class="form">
|
||||||
|
<?php $form=$this->beginWidget('CActiveForm', array(
|
||||||
|
'id'=>'login-form',
|
||||||
|
'enableAjaxValidation'=>true,
|
||||||
|
)); ?>
|
||||||
|
|
||||||
|
<p class="note">Fields with <span class="required">*</span> are required.</p>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<?php echo $form->labelEx($model,'username'); ?>
|
||||||
|
<?php echo $form->textField($model,'username'); ?>
|
||||||
|
<?php echo $form->error($model,'username'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<?php echo $form->labelEx($model,'password'); ?>
|
||||||
|
<?php echo $form->passwordField($model,'password'); ?>
|
||||||
|
<?php echo $form->error($model,'password'); ?>
|
||||||
|
<p class="hint">
|
||||||
|
Hint: You may login with <tt>demo/demo</tt>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row rememberMe">
|
||||||
|
<?php echo $form->checkBox($model,'rememberMe'); ?>
|
||||||
|
<?php echo $form->label($model,'rememberMe'); ?>
|
||||||
|
<?php echo $form->error($model,'rememberMe'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row submit">
|
||||||
|
<?php echo CHtml::submitButton('Login'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php $this->endWidget(); ?>
|
||||||
|
</div><!-- form -->
|
9
demos/blog/protected/views/site/pages/about.php
Normal file
9
demos/blog/protected/views/site/pages/about.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
$this->pageTitle=Yii::app()->name . ' - About';
|
||||||
|
$this->breadcrumbs=array(
|
||||||
|
'About',
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
<h1>About</h1>
|
||||||
|
|
||||||
|
<p>This is the "about" page for my blog site.</p>
|
4
demos/blog/protected/yiic
Normal file
4
demos/blog/protected/yiic
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once(dirname(__FILE__).'/yiic.php');
|
16
demos/blog/protected/yiic.bat
Normal file
16
demos/blog/protected/yiic.bat
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
rem -------------------------------------------------------------
|
||||||
|
rem Yii command line script for Windows.
|
||||||
|
rem This is the bootstrap script for running yiic on Windows.
|
||||||
|
rem -------------------------------------------------------------
|
||||||
|
|
||||||
|
@setlocal
|
||||||
|
|
||||||
|
set BIN_PATH=%~dp0
|
||||||
|
|
||||||
|
if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe
|
||||||
|
|
||||||
|
%PHP_COMMAND% "%BIN_PATH%yiic.php" %*
|
||||||
|
|
||||||
|
@endlocal
|
7
demos/blog/protected/yiic.php
Normal file
7
demos/blog/protected/yiic.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// change the following paths if necessary
|
||||||
|
$yiic=dirname(__FILE__).'/../../../framework/yiic.php';
|
||||||
|
$config=dirname(__FILE__).'/config/console.php';
|
||||||
|
|
||||||
|
require_once($yiic);
|
1
demos/blog/themes/classic/views/.htaccess
Normal file
1
demos/blog/themes/classic/views/.htaccess
Normal file
@ -0,0 +1 @@
|
|||||||
|
deny from all
|
0
demos/hangman/assets/empty
Normal file
0
demos/hangman/assets/empty
Normal file
7
demos/hangman/index.php
Normal file
7
demos/hangman/index.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$yii=dirname(__FILE__).'/../../framework/yii.php';
|
||||||
|
$config=dirname(__FILE__).'/protected/config/main.php';
|
||||||
|
|
||||||
|
require_once($yii);
|
||||||
|
Yii::createWebApplication($config)->run();
|
1
demos/hangman/protected/.htaccess
Normal file
1
demos/hangman/protected/.htaccess
Normal file
@ -0,0 +1 @@
|
|||||||
|
deny from all
|
14
demos/hangman/protected/config/main.php
Normal file
14
demos/hangman/protected/config/main.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'name'=>'Hangman Game',
|
||||||
|
'defaultController'=>'game',
|
||||||
|
'components'=>array(
|
||||||
|
'urlManager'=>array(
|
||||||
|
'urlFormat'=>'path',
|
||||||
|
'rules'=>array(
|
||||||
|
'game/guess/<g:\w>'=>'game/guess',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
222
demos/hangman/protected/controllers/GameController.php
Normal file
222
demos/hangman/protected/controllers/GameController.php
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* GameController class file.
|
||||||
|
*
|
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||||
|
* @link http://www.yiiframework.com/
|
||||||
|
* @copyright 2008-2013 Yii Software LLC
|
||||||
|
* @license http://www.yiiframework.com/license/
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GameController implements the {@link http://en.wikipedia.org/wiki/Hangman_(game) Hangman game}.
|
||||||
|
*
|
||||||
|
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||||
|
* @version $Id: CController.php 131 2008-11-02 01:32:57Z qiang.xue $
|
||||||
|
* @package demos.hangman
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
class GameController extends CController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string sets the default action to be 'play'
|
||||||
|
*/
|
||||||
|
public $defaultAction='play';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The 'play' action.
|
||||||
|
* In this action, users are asked to choose a difficulty level
|
||||||
|
* of the game.
|
||||||
|
*/
|
||||||
|
public function actionPlay()
|
||||||
|
{
|
||||||
|
static $levels=array(
|
||||||
|
'10'=>'Easy game; you are allowed 10 misses.',
|
||||||
|
'5'=>'Medium game; you are allowed 5 misses.',
|
||||||
|
'3'=>'Hard game; you are allowed 3 misses.',
|
||||||
|
);
|
||||||
|
|
||||||
|
// if a difficulty level is correctly chosen
|
||||||
|
if(isset($_POST['level']) && isset($levels[$_POST['level']]))
|
||||||
|
{
|
||||||
|
$this->word=$this->generateWord();
|
||||||
|
$this->guessWord=str_repeat('_',strlen($this->word));
|
||||||
|
$this->level=$_POST['level'];
|
||||||
|
$this->misses=0;
|
||||||
|
$this->setPageState('guessed',null);
|
||||||
|
// show the guess page
|
||||||
|
$this->render('guess');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$params=array(
|
||||||
|
'levels'=>$levels,
|
||||||
|
// if this is a POST request, it means the level is not chosen
|
||||||
|
'error'=>Yii::app()->request->isPostRequest,
|
||||||
|
);
|
||||||
|
// show the difficulty level page
|
||||||
|
$this->render('play',$params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The 'guess' action.
|
||||||
|
* This action is invoked each time when the user makes a guess.
|
||||||
|
*/
|
||||||
|
public function actionGuess()
|
||||||
|
{
|
||||||
|
// check to see if the letter is guessed correctly
|
||||||
|
if(isset($_GET['g'][0]) && ($result=$this->guess($_GET['g'][0]))!==null)
|
||||||
|
$this->render($result ? 'win' : 'lose');
|
||||||
|
else // the letter is guessed correctly, but not win yet
|
||||||
|
{
|
||||||
|
$guessed=$this->getPageState('guessed',array());
|
||||||
|
$guessed[$_GET['g'][0]]=true;
|
||||||
|
$this->setPageState('guessed',$guessed,array());
|
||||||
|
$this->render('guess');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The 'guess' action.
|
||||||
|
* This action is invoked when the user gives up the game.
|
||||||
|
*/
|
||||||
|
public function actionGiveup()
|
||||||
|
{
|
||||||
|
$this->render('lose');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if a letter is already guessed.
|
||||||
|
* @param string the letter
|
||||||
|
* @return boolean whether the letter is already guessed.
|
||||||
|
*/
|
||||||
|
public function isGuessed($letter)
|
||||||
|
{
|
||||||
|
$guessed=$this->getPageState('guessed',array());
|
||||||
|
return isset($guessed[$letter]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a word to be guessed.
|
||||||
|
* @return string the word to be guessed
|
||||||
|
*/
|
||||||
|
protected function generateWord()
|
||||||
|
{
|
||||||
|
$wordFile=dirname(__FILE__).'/words.txt';
|
||||||
|
$words=preg_split("/[\s,]+/",file_get_contents($wordFile));
|
||||||
|
do
|
||||||
|
{
|
||||||
|
$i=rand(0,count($words)-1);
|
||||||
|
$word=$words[$i];
|
||||||
|
} while(strlen($word)<5 || !ctype_alpha($word));
|
||||||
|
return strtoupper($word);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if a letter is guessed correctly.
|
||||||
|
* @param string the letter
|
||||||
|
* @return mixed true if the word is guessed correctly, false
|
||||||
|
* if the user has used up all guesses and the word is guessed
|
||||||
|
* incorrectly, and null if the letter is guessed correctly but
|
||||||
|
* the whole word is guessed correctly yet.
|
||||||
|
*/
|
||||||
|
protected function guess($letter)
|
||||||
|
{
|
||||||
|
$word=$this->word;
|
||||||
|
$guessWord=$this->guessWord;
|
||||||
|
$pos=0;
|
||||||
|
$success=false;
|
||||||
|
while(($pos=strpos($word,$letter,$pos))!==false)
|
||||||
|
{
|
||||||
|
$guessWord[$pos]=$letter;
|
||||||
|
$success=true;
|
||||||
|
$pos++;
|
||||||
|
}
|
||||||
|
if($success)
|
||||||
|
{
|
||||||
|
$this->guessWord=$guessWord;
|
||||||
|
if($guessWord===$word)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->misses++;
|
||||||
|
if($this->misses>=$this->level)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return integer the difficulty level. This value is persistent
|
||||||
|
* during the whole game session.
|
||||||
|
*/
|
||||||
|
public function getLevel()
|
||||||
|
{
|
||||||
|
return $this->getPageState('level');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param integer the difficulty level. This value is persistent
|
||||||
|
* during the whole game session.
|
||||||
|
*/
|
||||||
|
public function setLevel($value)
|
||||||
|
{
|
||||||
|
$this->setPageState('level',$value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string the word to be guessed. This value is persistent
|
||||||
|
* during the whole game session.
|
||||||
|
*/
|
||||||
|
public function getWord()
|
||||||
|
{
|
||||||
|
return $this->getPageState('word');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string the word to be guessed. This value is persistent
|
||||||
|
* during the whole game session.
|
||||||
|
*/
|
||||||
|
public function setWord($value)
|
||||||
|
{
|
||||||
|
$this->setPageState('word',$value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string the word being guessed. This value is persistent
|
||||||
|
* during the whole game session.
|
||||||
|
*/
|
||||||
|
public function getGuessWord()
|
||||||
|
{
|
||||||
|
return $this->getPageState('guessWord');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string the word being guessed. This value is persistent
|
||||||
|
* during the whole game session.
|
||||||
|
*/
|
||||||
|
public function setGuessWord($value)
|
||||||
|
{
|
||||||
|
$this->setPageState('guessWord',$value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return integer the number of misses. This value is persistent
|
||||||
|
* during the whole game session.
|
||||||
|
*/
|
||||||
|
public function getMisses()
|
||||||
|
{
|
||||||
|
return $this->getPageState('misses');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param integer the number of misses. This value is persistent
|
||||||
|
* during the whole game session.
|
||||||
|
*/
|
||||||
|
public function setMisses($value)
|
||||||
|
{
|
||||||
|
$this->setPageState('misses',$value);
|
||||||
|
}
|
||||||
|
}
|
28
demos/hangman/protected/controllers/words.txt
Normal file
28
demos/hangman/protected/controllers/words.txt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
Neither the name of Yii Software LLC nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
0
demos/hangman/protected/runtime/empty
Normal file
0
demos/hangman/protected/runtime/empty
Normal file
21
demos/hangman/protected/views/game/guess.php
Normal file
21
demos/hangman/protected/views/game/guess.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<h2>Please make a guess</h2>
|
||||||
|
|
||||||
|
<h3 style="letter-spacing: 4px;"><?php echo $this->guessWord; ?></h3>
|
||||||
|
|
||||||
|
<p>You have made <?php echo $this->misses; ?> bad guesses out of a maximum of <?php echo $this->level; ?>.</p>
|
||||||
|
|
||||||
|
<?php echo CHtml::statefulForm(); ?>
|
||||||
|
|
||||||
|
<p>Guess:
|
||||||
|
<?php
|
||||||
|
for($i=ord('A');$i<=ord('Z');++$i)
|
||||||
|
{
|
||||||
|
if(!$this->isGuessed(chr($i)))
|
||||||
|
echo "\n".CHtml::linkButton(chr($i),array('submit'=>array('guess','g'=>chr($i))));
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><?php echo CHtml::linkButton('Give up?',array('submit'=>array('giveup'))); ?></p>
|
||||||
|
|
||||||
|
</form>
|
5
demos/hangman/protected/views/game/lose.php
Normal file
5
demos/hangman/protected/views/game/lose.php
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<h2>You Lose!</h2>
|
||||||
|
|
||||||
|
<p>The word was: <?php echo $this->word; ?>.</p>
|
||||||
|
|
||||||
|
<p><?php echo CHtml::link('Start Again',array('play')); ?></p>
|
15
demos/hangman/protected/views/game/play.php
Normal file
15
demos/hangman/protected/views/game/play.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<p>This is the game of Hangman. You must guess a word, a letter at a time.
|
||||||
|
If you make too many mistakes, you lose the game!</p>
|
||||||
|
|
||||||
|
<?php echo CHtml::beginForm(); ?>
|
||||||
|
|
||||||
|
<?php echo CHtml::radioButtonList('level', null, $levels); ?>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<?php echo CHtml::submitButton('Play!'); ?>
|
||||||
|
|
||||||
|
<?php if($error): ?>
|
||||||
|
<span style="color:red">You must choose a difficulty level!</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php echo CHtml::endForm(); ?>
|
5
demos/hangman/protected/views/game/win.php
Normal file
5
demos/hangman/protected/views/game/win.php
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<h2>You Win!</h2>
|
||||||
|
|
||||||
|
<p>The word was: <?php echo $this->word; ?>.</p>
|
||||||
|
|
||||||
|
<p><?php echo CHtml::link('Start Again',array('play')); ?></p>
|
14
demos/hangman/protected/views/layouts/main.php
Normal file
14
demos/hangman/protected/views/layouts/main.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<title>Hangman Game</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Hangman Game</h1>
|
||||||
|
|
||||||
|
<?php echo $content; ?>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
7
demos/helloworld/index.php
Normal file
7
demos/helloworld/index.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// include Yii bootstrap file
|
||||||
|
require_once(dirname(__FILE__).'/../../framework/yii.php');
|
||||||
|
|
||||||
|
// create a Web application instance and run
|
||||||
|
Yii::createWebApplication()->run();
|
1
demos/helloworld/protected/.htaccess
Normal file
1
demos/helloworld/protected/.htaccess
Normal file
@ -0,0 +1 @@
|
|||||||
|
deny from all
|
15
demos/helloworld/protected/controllers/SiteController.php
Normal file
15
demos/helloworld/protected/controllers/SiteController.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SiteController is the default controller to handle user requests.
|
||||||
|
*/
|
||||||
|
class SiteController extends CController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Index action is the default action in a controller.
|
||||||
|
*/
|
||||||
|
public function actionIndex()
|
||||||
|
{
|
||||||
|
echo 'Hello World';
|
||||||
|
}
|
||||||
|
}
|
24
demos/phonebook/flex/.actionScriptProperties
Normal file
24
demos/phonebook/flex/.actionScriptProperties
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<actionScriptProperties version="1" mainApplicationPath="phonebook.mxml">
|
||||||
|
<compiler additionalCompilerArguments="-locale en_US" copyDependentFiles="true" generateAccessible="false" strict="true" warn="true" htmlGenerate="true" htmlPlayerVersionCheck="true" htmlPlayerVersion="9.0.0" htmlExpressInstall="true" htmlHistoryManagement="true" outputFolderPath="bin">
|
||||||
|
<compilerSourcePath/>
|
||||||
|
<libraryPath>
|
||||||
|
<libraryPathEntry kind="3" path="${FRAMEWORKS}/libs/playerglobal.swc" linkType="2"/>
|
||||||
|
<libraryPathEntry kind="3" path="${FRAMEWORKS}/libs/utilities.swc" linkType="1"/>
|
||||||
|
<libraryPathEntry kind="3" path="${FRAMEWORKS}/libs/flex.swc" linkType="1" sourcepath="${FRAMEWORKS}/source"/>
|
||||||
|
<libraryPathEntry kind="3" path="${FRAMEWORKS}/libs/framework.swc" linkType="1" sourcepath="${FRAMEWORKS}/source"/>
|
||||||
|
<libraryPathEntry kind="3" path="${FRAMEWORKS}/libs/rpc.swc" linkType="1"/>
|
||||||
|
<libraryPathEntry kind="3" path="${FRAMEWORKS}/libs/charts.swc" linkType="1" sourcepath="${FRAMEWORKS}/source"/>
|
||||||
|
<libraryPathEntry kind="1" path="${FRAMEWORKS}/locale/{locale}" linkType="1"/>
|
||||||
|
</libraryPath>
|
||||||
|
<sourceAttachmentPath>
|
||||||
|
<sourceAttachmentPathEntry kind="3" path="${FRAMEWORKS}/libs/flex.swc" linkType="1" sourcepath="${FRAMEWORKS}/source"/>
|
||||||
|
<sourceAttachmentPathEntry kind="3" path="${FRAMEWORKS}/libs/framework.swc" linkType="1" sourcepath="${FRAMEWORKS}/source"/>
|
||||||
|
<sourceAttachmentPathEntry kind="3" path="${FRAMEWORKS}/libs/charts.swc" linkType="1" sourcepath="${FRAMEWORKS}/source"/>
|
||||||
|
</sourceAttachmentPath>
|
||||||
|
</compiler>
|
||||||
|
<applications>
|
||||||
|
<application path="phonebook.mxml"/>
|
||||||
|
</applications>
|
||||||
|
<buildCSSFiles/>
|
||||||
|
</actionScriptProperties>
|
2
demos/phonebook/flex/.flexProperties
Normal file
2
demos/phonebook/flex/.flexProperties
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<flexProperties version="1" toolCompile="true" flexServerType="0"/>
|
276
demos/phonebook/flex/bin/AC_OETags.js
Normal file
276
demos/phonebook/flex/bin/AC_OETags.js
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
// Flash Player Version Detection - Rev 1.6
|
||||||
|
// Detect Client Browser type
|
||||||
|
// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved.
|
||||||
|
var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
|
||||||
|
var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
|
||||||
|
var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
|
||||||
|
|
||||||
|
function ControlVersion()
|
||||||
|
{
|
||||||
|
var version;
|
||||||
|
var axo;
|
||||||
|
var e;
|
||||||
|
|
||||||
|
// NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry
|
||||||
|
|
||||||
|
try {
|
||||||
|
// version will be set for 7.X or greater players
|
||||||
|
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
|
||||||
|
version = axo.GetVariable("$version");
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!version)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// version will be set for 6.X players only
|
||||||
|
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
|
||||||
|
|
||||||
|
// installed player is some revision of 6.0
|
||||||
|
// GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
|
||||||
|
// so we have to be careful.
|
||||||
|
|
||||||
|
// default to the first public version
|
||||||
|
version = "WIN 6,0,21,0";
|
||||||
|
|
||||||
|
// throws if AllowScripAccess does not exist (introduced in 6.0r47)
|
||||||
|
axo.AllowScriptAccess = "always";
|
||||||
|
|
||||||
|
// safe to call for 6.0r47 or greater
|
||||||
|
version = axo.GetVariable("$version");
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!version)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// version will be set for 4.X or 5.X player
|
||||||
|
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
|
||||||
|
version = axo.GetVariable("$version");
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!version)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// version will be set for 3.X player
|
||||||
|
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
|
||||||
|
version = "WIN 3,0,18,0";
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!version)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// version will be set for 2.X player
|
||||||
|
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
|
||||||
|
version = "WIN 2,0,0,11";
|
||||||
|
} catch (e) {
|
||||||
|
version = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
// JavaScript helper required to detect Flash Player PlugIn version information
|
||||||
|
function GetSwfVer(){
|
||||||
|
// NS/Opera version >= 3 check for Flash plugin in plugin array
|
||||||
|
var flashVer = -1;
|
||||||
|
|
||||||
|
if (navigator.plugins != null && navigator.plugins.length > 0) {
|
||||||
|
if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
|
||||||
|
var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
|
||||||
|
var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
|
||||||
|
var descArray = flashDescription.split(" ");
|
||||||
|
var tempArrayMajor = descArray[2].split(".");
|
||||||
|
var versionMajor = tempArrayMajor[0];
|
||||||
|
var versionMinor = tempArrayMajor[1];
|
||||||
|
var versionRevision = descArray[3];
|
||||||
|
if (versionRevision == "") {
|
||||||
|
versionRevision = descArray[4];
|
||||||
|
}
|
||||||
|
if (versionRevision[0] == "d") {
|
||||||
|
versionRevision = versionRevision.substring(1);
|
||||||
|
} else if (versionRevision[0] == "r") {
|
||||||
|
versionRevision = versionRevision.substring(1);
|
||||||
|
if (versionRevision.indexOf("d") > 0) {
|
||||||
|
versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// MSN/WebTV 2.6 supports Flash 4
|
||||||
|
else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
|
||||||
|
// WebTV 2.5 supports Flash 3
|
||||||
|
else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
|
||||||
|
// older WebTV supports Flash 2
|
||||||
|
else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
|
||||||
|
else if ( isIE && isWin && !isOpera ) {
|
||||||
|
flashVer = ControlVersion();
|
||||||
|
}
|
||||||
|
return flashVer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
|
||||||
|
function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision)
|
||||||
|
{
|
||||||
|
versionStr = GetSwfVer();
|
||||||
|
if (versionStr == -1 ) {
|
||||||
|
return false;
|
||||||
|
} else if (versionStr != 0) {
|
||||||
|
if(isIE && isWin && !isOpera) {
|
||||||
|
// Given "WIN 2,0,0,11"
|
||||||
|
tempArray = versionStr.split(" "); // ["WIN", "2,0,0,11"]
|
||||||
|
tempString = tempArray[1]; // "2,0,0,11"
|
||||||
|
versionArray = tempString.split(","); // ['2', '0', '0', '11']
|
||||||
|
} else {
|
||||||
|
versionArray = versionStr.split(".");
|
||||||
|
}
|
||||||
|
var versionMajor = versionArray[0];
|
||||||
|
var versionMinor = versionArray[1];
|
||||||
|
var versionRevision = versionArray[2];
|
||||||
|
|
||||||
|
// is the major.revision >= requested major.revision AND the minor version >= requested minor
|
||||||
|
if (versionMajor > parseFloat(reqMajorVer)) {
|
||||||
|
return true;
|
||||||
|
} else if (versionMajor == parseFloat(reqMajorVer)) {
|
||||||
|
if (versionMinor > parseFloat(reqMinorVer))
|
||||||
|
return true;
|
||||||
|
else if (versionMinor == parseFloat(reqMinorVer)) {
|
||||||
|
if (versionRevision >= parseFloat(reqRevision))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function AC_AddExtension(src, ext)
|
||||||
|
{
|
||||||
|
if (src.indexOf('?') != -1)
|
||||||
|
return src.replace(/\?/, ext+'?');
|
||||||
|
else
|
||||||
|
return src + ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
function AC_Generateobj(objAttrs, params, embedAttrs)
|
||||||
|
{
|
||||||
|
var str = '';
|
||||||
|
if (isIE && isWin && !isOpera)
|
||||||
|
{
|
||||||
|
str += '<object ';
|
||||||
|
for (var i in objAttrs)
|
||||||
|
str += i + '="' + objAttrs[i] + '" ';
|
||||||
|
str += '>';
|
||||||
|
for (var i in params)
|
||||||
|
str += '<param name="' + i + '" value="' + params[i] + '" /> ';
|
||||||
|
str += '</object>';
|
||||||
|
} else {
|
||||||
|
str += '<embed ';
|
||||||
|
for (var i in embedAttrs)
|
||||||
|
str += i + '="' + embedAttrs[i] + '" ';
|
||||||
|
str += '> </embed>';
|
||||||
|
}
|
||||||
|
|
||||||
|
document.write(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
function AC_FL_RunContent(){
|
||||||
|
var ret =
|
||||||
|
AC_GetArgs
|
||||||
|
( arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
|
||||||
|
, "application/x-shockwave-flash"
|
||||||
|
);
|
||||||
|
AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
function AC_GetArgs(args, ext, srcParamName, classid, mimeType){
|
||||||
|
var ret = new Object();
|
||||||
|
ret.embedAttrs = new Object();
|
||||||
|
ret.params = new Object();
|
||||||
|
ret.objAttrs = new Object();
|
||||||
|
for (var i=0; i < args.length; i=i+2){
|
||||||
|
var currArg = args[i].toLowerCase();
|
||||||
|
|
||||||
|
switch (currArg){
|
||||||
|
case "classid":
|
||||||
|
break;
|
||||||
|
case "pluginspage":
|
||||||
|
ret.embedAttrs[args[i]] = args[i+1];
|
||||||
|
break;
|
||||||
|
case "src":
|
||||||
|
case "movie":
|
||||||
|
args[i+1] = AC_AddExtension(args[i+1], ext);
|
||||||
|
ret.embedAttrs["src"] = args[i+1];
|
||||||
|
ret.params[srcParamName] = args[i+1];
|
||||||
|
break;
|
||||||
|
case "onafterupdate":
|
||||||
|
case "onbeforeupdate":
|
||||||
|
case "onblur":
|
||||||
|
case "oncellchange":
|
||||||
|
case "onclick":
|
||||||
|
case "ondblClick":
|
||||||
|
case "ondrag":
|
||||||
|
case "ondragend":
|
||||||
|
case "ondragenter":
|
||||||
|
case "ondragleave":
|
||||||
|
case "ondragover":
|
||||||
|
case "ondrop":
|
||||||
|
case "onfinish":
|
||||||
|
case "onfocus":
|
||||||
|
case "onhelp":
|
||||||
|
case "onmousedown":
|
||||||
|
case "onmouseup":
|
||||||
|
case "onmouseover":
|
||||||
|
case "onmousemove":
|
||||||
|
case "onmouseout":
|
||||||
|
case "onkeypress":
|
||||||
|
case "onkeydown":
|
||||||
|
case "onkeyup":
|
||||||
|
case "onload":
|
||||||
|
case "onlosecapture":
|
||||||
|
case "onpropertychange":
|
||||||
|
case "onreadystatechange":
|
||||||
|
case "onrowsdelete":
|
||||||
|
case "onrowenter":
|
||||||
|
case "onrowexit":
|
||||||
|
case "onrowsinserted":
|
||||||
|
case "onstart":
|
||||||
|
case "onscroll":
|
||||||
|
case "onbeforeeditfocus":
|
||||||
|
case "onactivate":
|
||||||
|
case "onbeforedeactivate":
|
||||||
|
case "ondeactivate":
|
||||||
|
case "type":
|
||||||
|
case "codebase":
|
||||||
|
ret.objAttrs[args[i]] = args[i+1];
|
||||||
|
break;
|
||||||
|
case "id":
|
||||||
|
case "width":
|
||||||
|
case "height":
|
||||||
|
case "align":
|
||||||
|
case "vspace":
|
||||||
|
case "hspace":
|
||||||
|
case "class":
|
||||||
|
case "title":
|
||||||
|
case "accesskey":
|
||||||
|
case "name":
|
||||||
|
case "tabindex":
|
||||||
|
ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret.objAttrs["classid"] = classid;
|
||||||
|
if (mimeType) ret.embedAttrs["type"] = mimeType;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user