diff --git a/.gitignore b/.gitignore index d8b54c0..832a890 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,4 @@ nbproject Thumbs.db # composer vendor dir -/framework/vendor \ No newline at end of file +/yii/vendor \ No newline at end of file diff --git a/apps/bootstrap/index.php b/apps/bootstrap/index.php index e3188c1..c046b69 100644 --- a/apps/bootstrap/index.php +++ b/apps/bootstrap/index.php @@ -1,8 +1,12 @@ 'hello', 'basePath' => dirname(__DIR__), 'preload' => array('log'), + 'modules' => array( + 'debug' => array( + 'class' => 'yii\debug\Module', + ) + ), 'components' => array( 'cache' => array( 'class' => 'yii\caching\FileCache', diff --git a/apps/bootstrap/protected/controllers/SiteController.php b/apps/bootstrap/protected/controllers/SiteController.php index d1186f6..b06ed06 100644 --- a/apps/bootstrap/protected/controllers/SiteController.php +++ b/apps/bootstrap/protected/controllers/SiteController.php @@ -6,6 +6,15 @@ use app\models\ContactForm; class SiteController extends Controller { + public function actions() + { + return array( + 'captcha' => array( + 'class' => 'yii\web\CaptchaAction', + ), + ); + } + public function actionIndex() { echo $this->render('index'); diff --git a/apps/bootstrap/protected/models/ContactForm.php b/apps/bootstrap/protected/models/ContactForm.php index 5124b2c..7b713a1 100644 --- a/apps/bootstrap/protected/models/ContactForm.php +++ b/apps/bootstrap/protected/models/ContactForm.php @@ -26,7 +26,7 @@ class ContactForm extends Model // email has to be a valid email address array('email', 'email'), // verifyCode needs to be entered correctly - //array('verifyCode', 'captcha', 'allowEmpty' => !Captcha::checkRequirements()), + array('verifyCode', 'captcha'), ); } diff --git a/apps/bootstrap/protected/views/layouts/main.php b/apps/bootstrap/protected/views/layouts/main.php index 1e8a3af..a81f983 100644 --- a/apps/bootstrap/protected/views/layouts/main.php +++ b/apps/bootstrap/protected/views/layouts/main.php @@ -58,6 +58,7 @@ $this->registerAssetBundle('app'); endBody(); ?> +widget('yii\debug\Toolbar'); ?> endPage(); ?> diff --git a/apps/bootstrap/protected/views/site/contact.php b/apps/bootstrap/protected/views/site/contact.php index 4115b53..bee1ede 100644 --- a/apps/bootstrap/protected/views/site/contact.php +++ b/apps/bootstrap/protected/views/site/contact.php @@ -1,6 +1,7 @@ params['breadcrumbs'][] = $this->title; field($model, 'email')->textInput(); ?> field($model, 'subject')->textInput(); ?> field($model, 'body')->textArea(array('rows' => 6)); ?> + field($model, 'verifyCode'); + echo $field->begin(); + echo $field->label(); + $this->widget(Captcha::className()); + echo Html::activeTextInput($model, 'verifyCode', array('class' => 'input-medium')); + echo $field->error(); + echo $field->end(); + ?>
'btn btn-primary')); ?>
diff --git a/build/build b/build/build index 691eba9..95b51e4 100755 --- a/build/build +++ b/build/build @@ -11,7 +11,7 @@ // fcgi doesn't have STDIN defined by default defined('STDIN') or define('STDIN', fopen('php://stdin', 'r')); -require(__DIR__ . '/../framework/yii.php'); +require(__DIR__ . '/../framework/Yii.php'); $id = 'yiic-build'; $basePath = __DIR__; diff --git a/composer.json b/composer.json index c6b616a..e9c3927 100644 --- a/composer.json +++ b/composer.json @@ -64,10 +64,10 @@ "source": "https://github.com/yiisoft/yii2" }, "config": { - "vendor-dir": "framework/vendor" + "vendor-dir": "yii/vendor" }, "bin": [ - "framework/yiic" + "yii/yiic" ], "require": { "php": ">=5.3.0", diff --git a/tests/unit/DatabaseTestCase.php b/tests/unit/DatabaseTestCase.php new file mode 100644 index 0000000..b39c2e5 --- /dev/null +++ b/tests/unit/DatabaseTestCase.php @@ -0,0 +1,50 @@ +getParam('databases'); + $this->database = $databases[$this->driverName]; + $pdo_database = 'pdo_'.$this->driverName; + + if (!extension_loaded('pdo') || !extension_loaded($pdo_database)) { + $this->markTestSkipped('pdo and pdo_'.$pdo_database.' extension are required.'); + } + } + + /** + * @param bool $reset whether to clean up the test database + * @param bool $open whether to open and populate test database + * @return \yii\db\Connection + */ + public function getConnection($reset = true, $open = true) + { + if (!$reset && $this->db) { + return $this->db; + } + $db = new \yii\db\Connection; + $db->dsn = $this->database['dsn']; + if (isset($this->database['username'])) { + $db->username = $this->database['username']; + $db->password = $this->database['password']; + } + if ($open) { + $db->open(); + $lines = explode(';', file_get_contents($this->database['fixture'])); + foreach ($lines as $line) { + if (trim($line) !== '') { + $db->pdo->exec($line); + } + } + } + $this->db = $db; + return $db; + } +} diff --git a/tests/unit/bootstrap.php b/tests/unit/bootstrap.php index 8290bbe..285b55b 100644 --- a/tests/unit/bootstrap.php +++ b/tests/unit/bootstrap.php @@ -5,7 +5,7 @@ define('YII_DEBUG', true); $_SERVER['SCRIPT_NAME'] = '/' . __DIR__; $_SERVER['SCRIPT_FILENAME'] = __FILE__; -require_once(__DIR__ . '/../../framework/yii.php'); +require_once(__DIR__ . '/../../yii/Yii.php'); Yii::setAlias('@yiiunit', __DIR__); diff --git a/tests/unit/data/config.php b/tests/unit/data/config.php index 238a7cc..c980c57 100644 --- a/tests/unit/data/config.php +++ b/tests/unit/data/config.php @@ -1,10 +1,16 @@ array( - 'dsn' => 'mysql:host=127.0.0.1;dbname=yiitest', - 'username' => 'travis', - 'password' => '', - 'fixture' => __DIR__ . '/mysql.sql', - ), + 'databases' => array( + 'mysql' => array( + 'dsn' => 'mysql:host=127.0.0.1;dbname=yiitest', + 'username' => 'travis', + 'password' => '', + 'fixture' => __DIR__ . '/mysql.sql', + ), + 'sqlite' => array( + 'dsn' => 'sqlite::memory:', + 'fixture' => __DIR__ . '/sqlite.sql', + ), + ) ); diff --git a/tests/unit/data/mysql.sql b/tests/unit/data/mysql.sql index 8223f59..1bb5558 100644 --- a/tests/unit/data/mysql.sql +++ b/tests/unit/data/mysql.sql @@ -1,10 +1,6 @@ /** * This is the database schema for testing MySQL support of Yii DAO and Active Record. - * The following database setup is required to perform then relevant tests: - * Database name: yiitest - * username: test - * password: test - * charset: utf8 + * The database setup in config.php is required to perform then relevant tests: */ DROP TABLE IF EXISTS tbl_order_item CASCADE; diff --git a/tests/unit/data/sqlite.sql b/tests/unit/data/sqlite.sql index affeca9..f75bfa6 100644 --- a/tests/unit/data/sqlite.sql +++ b/tests/unit/data/sqlite.sql @@ -1,262 +1,88 @@ -CREATE TABLE users -( - id INTEGER NOT NULL PRIMARY KEY, - username VARCHAR(128) NOT NULL, - password VARCHAR(128) NOT NULL, - email VARCHAR(128) NOT NULL -); - -INSERT INTO users(id,username,password,email) VALUES (1,'user1','pass1','email1'); -INSERT INTO users(id,username,password,email) VALUES (2,'user2','pass2','email2'); -INSERT INTO users(id,username,password,email) VALUES (3,'user3','pass3','email3'); -INSERT INTO users(id,username,password,email) VALUES (4,'user4','pass4','email4'); - -CREATE TABLE groups -( - id INTEGER NOT NULL PRIMARY KEY, - name VARCHAR(128) NOT NULL -); - -INSERT INTO groups(id,name) VALUES (1,'group1'); -INSERT INTO groups(id,name) VALUES (2,'group2'); -INSERT INTO groups(id,name) VALUES (3,'group3'); -INSERT INTO groups(id,name) VALUES (4,'group4'); -INSERT INTO groups(id,name) VALUES (5,'group5'); -INSERT INTO groups(id,name) VALUES (6,'group6'); - -CREATE TABLE groups_descriptions -( - group_id INTEGER NOT NULL PRIMARY KEY, - name VARCHAR(128) NOT NULL -); - -INSERT INTO groups_descriptions(group_id,name) VALUES (1,'room1'); -INSERT INTO groups_descriptions(group_id,name) VALUES (2,'room2'); -INSERT INTO groups_descriptions(group_id,name) VALUES (3,'room3'); -INSERT INTO groups_descriptions(group_id,name) VALUES (4,'room4'); - -CREATE TABLE roles -( - user_id INTEGER NOT NULL, - group_id INTEGER NOT NULL, - name VARCHAR(128) NOT NULL, - PRIMARY KEY(user_id,group_id) -); - -INSERT INTO roles(user_id,group_id,name) VALUES (1,1,'dev'); -INSERT INTO roles(user_id,group_id,name) VALUES (1,2,'user'); -INSERT INTO roles(user_id,group_id,name) VALUES (2,1,'dev'); -INSERT INTO roles(user_id,group_id,name) VALUES (2,3,'user'); - -CREATE TABLE mentorships -( - teacher_id INTEGER NOT NULL, - student_id INTEGER NOT NULL, - progress VARCHAR(128) NOT NULL, - PRIMARY KEY(teacher_id,student_id) -); - -INSERT INTO mentorships(teacher_id,student_id,progress) VALUES (1,3,'good'); -INSERT INTO mentorships(teacher_id,student_id,progress) VALUES (2,4,'average'); - -CREATE TABLE profiles -( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - first_name VARCHAR(128) NOT NULL, - last_name VARCHAR(128) NOT NULL, - user_id INTEGER NOT NULL, - CONSTRAINT FK_profile_user FOREIGN KEY (user_id) - REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT -); - -INSERT INTO profiles (first_name, last_name, user_id) VALUES ('first 1','last 1',1); -INSERT INTO profiles (first_name, last_name, user_id) VALUES ('first 2','last 2',2); - -CREATE TABLE posts -( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - title VARCHAR(128) NOT NULL, - create_time TIMESTAMP NOT NULL, - author_id INTEGER NOT NULL, - content TEXT, - CONSTRAINT FK_post_author FOREIGN KEY (author_id) - REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT -); - -INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 1',100000,1,'content 1'); -INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 2',100001,2,'content 2'); -INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 3',100002,2,'content 3'); -INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 4',100003,2,'content 4'); -INSERT INTO posts (title, create_time, author_id, content) VALUES ('post 5',100004,3,'content 5'); - - -CREATE TABLE posts_nofk -( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - title VARCHAR(128) NOT NULL, - create_time TIMESTAMP NOT NULL, - author_id INTEGER NOT NULL, - content TEXT -); - -INSERT INTO posts_nofk (title, create_time, author_id, content) VALUES ('post 1',100000,1,'content 1'); -INSERT INTO posts_nofk (title, create_time, author_id, content) VALUES ('post 2',100001,2,'content 2'); -INSERT INTO posts_nofk (title, create_time, author_id, content) VALUES ('post 3',100002,2,'content 3'); -INSERT INTO posts_nofk (title, create_time, author_id, content) VALUES ('post 4',100003,2,'content 4'); -INSERT INTO posts_nofk (title, create_time, author_id, content) VALUES ('post 5',100004,3,'content 5'); - - -CREATE TABLE comments -( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - content TEXT NOT NULL, - post_id INTEGER NOT NULL, - author_id INTEGER NOT NULL, - CONSTRAINT FK_post_comment FOREIGN KEY (post_id) - REFERENCES posts (id) ON DELETE CASCADE ON UPDATE RESTRICT, - CONSTRAINT FK_user_comment FOREIGN KEY (author_id) - REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT -); - -INSERT INTO comments (content, post_id, author_id) VALUES ('comment 1',1, 2); -INSERT INTO comments (content, post_id, author_id) VALUES ('comment 2',1, 2); -INSERT INTO comments (content, post_id, author_id) VALUES ('comment 3',1, 2); -INSERT INTO comments (content, post_id, author_id) VALUES ('comment 4',2, 2); -INSERT INTO comments (content, post_id, author_id) VALUES ('comment 5',2, 2); -INSERT INTO comments (content, post_id, author_id) VALUES ('comment 6',3, 2); -INSERT INTO comments (content, post_id, author_id) VALUES ('comment 7',3, 2); -INSERT INTO comments (content, post_id, author_id) VALUES ('comment 8',3, 2); -INSERT INTO comments (content, post_id, author_id) VALUES ('comment 9',3, 2); -INSERT INTO comments (content, post_id, author_id) VALUES ('comment 10',5, 3); - -CREATE TABLE categories -( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - name VARCHAR(128) NOT NULL, - parent_id INTEGER, - CONSTRAINT FK_category_category FOREIGN KEY (parent_id) - REFERENCES categories (id) ON DELETE CASCADE ON UPDATE RESTRICT -); - -INSERT INTO categories (name, parent_id) VALUES ('cat 1',NULL); -INSERT INTO categories (name, parent_id) VALUES ('cat 2',NULL); -INSERT INTO categories (name, parent_id) VALUES ('cat 3',NULL); -INSERT INTO categories (name, parent_id) VALUES ('cat 4',1); -INSERT INTO categories (name, parent_id) VALUES ('cat 5',1); -INSERT INTO categories (name, parent_id) VALUES ('cat 6',5); -INSERT INTO categories (name, parent_id) VALUES ('cat 7',5); - -CREATE TABLE post_category -( - category_id INTEGER NOT NULL, - post_id INTEGER NOT NULL, - PRIMARY KEY (category_id, post_id), - CONSTRAINT FK_post_category_post FOREIGN KEY (post_id) - REFERENCES posts (id) ON DELETE CASCADE ON UPDATE RESTRICT, - CONSTRAINT FK_post_category_category FOREIGN KEY (category_id) - REFERENCES categories (id) ON DELETE CASCADE ON UPDATE RESTRICT -); - -INSERT INTO post_category (category_id, post_id) VALUES (1,1); -INSERT INTO post_category (category_id, post_id) VALUES (2,1); -INSERT INTO post_category (category_id, post_id) VALUES (3,1); -INSERT INTO post_category (category_id, post_id) VALUES (4,2); -INSERT INTO post_category (category_id, post_id) VALUES (1,2); -INSERT INTO post_category (category_id, post_id) VALUES (1,3); - -CREATE TABLE orders -( - key1 INTEGER NOT NULL, - key2 INTEGER NOT NULL, - name VARCHAR(128), - PRIMARY KEY (key1, key2) -); - -INSERT INTO orders (key1,key2,name) VALUES (1,2,'order 12'); -INSERT INTO orders (key1,key2,name) VALUES (1,3,'order 13'); -INSERT INTO orders (key1,key2,name) VALUES (2,1,'order 21'); -INSERT INTO orders (key1,key2,name) VALUES (2,2,'order 22'); - -CREATE TABLE items -( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - name VARCHAR(128), - col1 INTEGER NOT NULL, - col2 INTEGER NOT NULL, - CONSTRAINT FK_order_item FOREIGN KEY (col1,col2) - REFERENCES orders (key1,key2) ON DELETE CASCADE ON UPDATE RESTRICT -); - -INSERT INTO items (name,col1,col2) VALUES ('item 1',1,2); -INSERT INTO items (name,col1,col2) VALUES ('item 2',1,2); -INSERT INTO items (name,col1,col2) VALUES ('item 3',1,3); -INSERT INTO items (name,col1,col2) VALUES ('item 4',2,2); -INSERT INTO items (name,col1,col2) VALUES ('item 5',2,2); - -CREATE TABLE types -( - int_col INT NOT NULL, - int_col2 INTEGER DEFAULT 1, - char_col CHAR(100) NOT NULL, - char_col2 VARCHAR(100) DEFAULT 'something', - char_col3 TEXT, - float_col REAL(4,3) NOT NULL, - float_col2 DOUBLE DEFAULT 1.23, - blob_col BLOB, - numeric_col NUMERIC(5,2) DEFAULT 33.22, - time TIMESTAMP DEFAULT 123, - bool_col BOOL NOT NULL, - bool_col2 BOOLEAN DEFAULT 1, - null_col INTEGER DEFAULT NULL -); - -CREATE TABLE Content -( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - class VARCHAR(128), - parentID INTEGER NOT NULL, - ownerID INTEGER NOT NULL, - title VARCHAR(100), - CONSTRAINT FK_content_user FOREIGN KEY (ownerID) - REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT - CONSTRAINT FK_content_parent FOREIGN KEY (parentID) - REFERENCES Content (id) ON DELETE CASCADE ON UPDATE RESTRICT -); - -INSERT INTO Content (class,parentID,ownerID,title) VALUES ('Article',-1,1,'article 1'); -INSERT INTO Content (class,parentID,ownerID,title) VALUES ('Article',-1,2,'article 2'); -INSERT INTO Content (class,parentID,ownerID,title) VALUES ('Comment',1,1,'comment 1'); -INSERT INTO Content (class,parentID,ownerID,title) VALUES ('Article',-1,2,'article 3'); -INSERT INTO Content (class,parentID,ownerID,title) VALUES ('Comment',4,2,'comment 2'); -INSERT INTO Content (class,parentID,ownerID,title) VALUES ('Comment',4,1,'comment 3'); - -CREATE TABLE Article -( - id INTEGER NOT NULL PRIMARY KEY, - authorID INTEGER NOT NULL, - body TEXT, - CONSTRAINT FK_article_content FOREIGN KEY (id) - REFERENCES Content (id) ON DELETE CASCADE ON UPDATE RESTRICT - CONSTRAINT FK_article_author FOREIGN KEY (authorID) - REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT -); - -INSERT INTO Article (id,authorID,body) VALUES (1,1,'content for article 1'); -INSERT INTO Article (id,authorID,body) VALUES (2,2,'content for article 2'); -INSERT INTO Article (id,authorID,body) VALUES (4,1,'content for article 3'); - -CREATE TABLE Comment -( - id INTEGER NOT NULL PRIMARY KEY, - authorID INTEGER NOT NULL, - body TEXT, - CONSTRAINT FK_comment_content FOREIGN KEY (id) - REFERENCES Content (id) ON DELETE CASCADE ON UPDATE RESTRICT - CONSTRAINT FK_article_author FOREIGN KEY (authorID) - REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT -); - -INSERT INTO Comment (id,authorID,body) VALUES (3,1,'content for comment 1'); -INSERT INTO Comment (id,authorID,body) VALUES (5,1,'content for comment 2'); -INSERT INTO Comment (id,authorID,body) VALUES (6,1,'content for comment 3'); - +/** + * This is the database schema for testing Sqlite support of Yii DAO and Active Record. + * The database setup in config.php is required to perform then relevant tests: + */ + +DROP TABLE IF EXISTS tbl_order_item; +DROP TABLE IF EXISTS tbl_item; +DROP TABLE IF EXISTS tbl_order; +DROP TABLE IF EXISTS tbl_category; +DROP TABLE IF EXISTS tbl_customer; +DROP TABLE IF EXISTS tbl_type; + +CREATE TABLE tbl_customer ( + id INTEGER NOT NULL, + email varchar(128) NOT NULL, + name varchar(128) NOT NULL, + address text, + status INTEGER DEFAULT 0, + PRIMARY KEY (id) +); + +CREATE TABLE tbl_category ( + id INTEGER NOT NULL, + name varchar(128) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE tbl_item ( + id INTEGER NOT NULL, + name varchar(128) NOT NULL, + category_id INTEGER NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE tbl_order ( + id INTEGER NOT NULL, + customer_id INTEGER NOT NULL, + create_time INTEGER NOT NULL, + total decimal(10,0) NOT NULL, + PRIMARY KEY (id) +); + +CREATE TABLE tbl_order_item ( + order_id INTEGER NOT NULL, + item_id INTEGER NOT NULL, + quantity INTEGER NOT NULL, + subtotal decimal(10,0) NOT NULL, + PRIMARY KEY (order_id, item_id) +); + +CREATE TABLE tbl_type ( + int_col INTEGER NOT NULL, + int_col2 INTEGER DEFAULT '1', + char_col char(100) NOT NULL, + char_col2 varchar(100) DEFAULT 'something', + char_col3 text, + float_col double(4,3) NOT NULL, + float_col2 double DEFAULT '1.23', + blob_col blob, + numeric_col decimal(5,2) DEFAULT '33.22', + time timestamp NOT NULL DEFAULT '2002-01-01 00:00:00', + bool_col tinyint(1) NOT NULL, + bool_col2 tinyint(1) DEFAULT '1' +); + +INSERT INTO tbl_customer (email, name, address, status) VALUES ('user1@example.com', 'user1', 'address1', 1); +INSERT INTO tbl_customer (email, name, address, status) VALUES ('user2@example.com', 'user2', 'address2', 1); +INSERT INTO tbl_customer (email, name, address, status) VALUES ('user3@example.com', 'user3', 'address3', 2); + +INSERT INTO tbl_category (name) VALUES ('Books'); +INSERT INTO tbl_category (name) VALUES ('Movies'); + +INSERT INTO tbl_item (name, category_id) VALUES ('Agile Web Application Development with Yii1.1 and PHP5', 1); +INSERT INTO tbl_item (name, category_id) VALUES ('Yii 1.1 Application Development Cookbook', 1); +INSERT INTO tbl_item (name, category_id) VALUES ('Ice Age', 2); +INSERT INTO tbl_item (name, category_id) VALUES ('Toy Story', 2); +INSERT INTO tbl_item (name, category_id) VALUES ('Cars', 2); + +INSERT INTO tbl_order (customer_id, create_time, total) VALUES (1, 1325282384, 110.0); +INSERT INTO tbl_order (customer_id, create_time, total) VALUES (2, 1325334482, 33.0); +INSERT INTO tbl_order (customer_id, create_time, total) VALUES (2, 1325502201, 40.0); + +INSERT INTO tbl_order_item (order_id, item_id, quantity, subtotal) VALUES (1, 1, 1, 30.0); +INSERT INTO tbl_order_item (order_id, item_id, quantity, subtotal) VALUES (1, 2, 2, 40.0); +INSERT INTO tbl_order_item (order_id, item_id, quantity, subtotal) VALUES (2, 4, 1, 10.0); +INSERT INTO tbl_order_item (order_id, item_id, quantity, subtotal) VALUES (2, 5, 1, 15.0); +INSERT INTO tbl_order_item (order_id, item_id, quantity, subtotal) VALUES (2, 3, 1, 8.0); +INSERT INTO tbl_order_item (order_id, item_id, quantity, subtotal) VALUES (3, 2, 1, 40.0); \ No newline at end of file diff --git a/tests/unit/framework/YiiBaseTest.php b/tests/unit/framework/YiiBaseTest.php index 47474f2..4ebf45c 100644 --- a/tests/unit/framework/YiiBaseTest.php +++ b/tests/unit/framework/YiiBaseTest.php @@ -47,7 +47,6 @@ class YiiBaseTest extends TestCase public function testGetVersion() { - echo Yii::getVersion(); $this->assertTrue((boolean)preg_match('~\d+\.\d+(?:\.\d+)?(?:-\w+)?~', \Yii::getVersion())); } diff --git a/tests/unit/framework/caching/DbCacheTest.php b/tests/unit/framework/caching/DbCacheTest.php index a41667c..253240d 100644 --- a/tests/unit/framework/caching/DbCacheTest.php +++ b/tests/unit/framework/caching/DbCacheTest.php @@ -35,7 +35,8 @@ class DbCacheTest extends CacheTest function getConnection($reset = true) { if($this->_connection === null) { - $params = $this->getParam('mysql'); + $databases = $this->getParam('databases'); + $params = $databases['mysql']; $db = new \yii\db\Connection; $db->dsn = $params['dsn']; $db->username = $params['username']; diff --git a/tests/unit/framework/db/ActiveRecordTest.php b/tests/unit/framework/db/ActiveRecordTest.php index f0ea968..e337a5d 100644 --- a/tests/unit/framework/db/ActiveRecordTest.php +++ b/tests/unit/framework/db/ActiveRecordTest.php @@ -10,10 +10,11 @@ use yiiunit\data\ar\OrderItem; use yiiunit\data\ar\Order; use yiiunit\data\ar\Item; -class ActiveRecordTest extends \yiiunit\MysqlTestCase +class ActiveRecordTest extends \yiiunit\DatabaseTestCase { public function setUp() { + parent::setUp(); ActiveRecord::$db = $this->getConnection(); } diff --git a/tests/unit/framework/db/CommandTest.php b/tests/unit/framework/db/CommandTest.php index 2576e78..0d9652b 100644 --- a/tests/unit/framework/db/CommandTest.php +++ b/tests/unit/framework/db/CommandTest.php @@ -7,7 +7,7 @@ use yii\db\Command; use yii\db\Query; use yii\db\DataReader; -class CommandTest extends \yiiunit\MysqlTestCase +class CommandTest extends \yiiunit\DatabaseTestCase { function testConstruct() { diff --git a/tests/unit/framework/db/ConnectionTest.php b/tests/unit/framework/db/ConnectionTest.php index 256c5a9..c837b95 100644 --- a/tests/unit/framework/db/ConnectionTest.php +++ b/tests/unit/framework/db/ConnectionTest.php @@ -4,12 +4,12 @@ namespace yiiunit\framework\db; use yii\db\Connection; -class ConnectionTest extends \yiiunit\MysqlTestCase +class ConnectionTest extends \yiiunit\DatabaseTestCase { function testConstruct() { $connection = $this->getConnection(false); - $params = $this->getParam('mysql'); + $params = $this->database; $this->assertEquals($params['dsn'], $connection->dsn); $this->assertEquals($params['username'], $connection->username); @@ -18,7 +18,7 @@ class ConnectionTest extends \yiiunit\MysqlTestCase function testOpenClose() { - $connection = $this->getConnection(false); + $connection = $this->getConnection(false, false); $this->assertFalse($connection->isActive); $this->assertEquals(null, $connection->pdo); @@ -39,9 +39,8 @@ class ConnectionTest extends \yiiunit\MysqlTestCase function testGetDriverName() { - $connection = $this->getConnection(false); - $this->assertEquals('mysql', $connection->driverName); - $this->assertFalse($connection->isActive); + $connection = $this->getConnection(false, false); + $this->assertEquals($this->driverName, $connection->driverName); } function testQuoteValue() diff --git a/tests/unit/framework/db/QueryTest.php b/tests/unit/framework/db/QueryTest.php index 1c730cd..398d0d9 100644 --- a/tests/unit/framework/db/QueryTest.php +++ b/tests/unit/framework/db/QueryTest.php @@ -7,7 +7,7 @@ use yii\db\Command; use yii\db\Query; use yii\db\DataReader; -class QueryTest extends \yiiunit\MysqlTestCase +class QueryTest extends \yiiunit\DatabaseTestCase { function testSelect() { diff --git a/tests/unit/framework/db/sqlite/SqliteActiveRecordTest.php b/tests/unit/framework/db/sqlite/SqliteActiveRecordTest.php new file mode 100644 index 0000000..539e879 --- /dev/null +++ b/tests/unit/framework/db/sqlite/SqliteActiveRecordTest.php @@ -0,0 +1,12 @@ +driverName = 'sqlite'; + parent::setUp(); + } +} diff --git a/tests/unit/framework/db/sqlite/SqliteCommandTest.php b/tests/unit/framework/db/sqlite/SqliteCommandTest.php new file mode 100644 index 0000000..4110cd3 --- /dev/null +++ b/tests/unit/framework/db/sqlite/SqliteCommandTest.php @@ -0,0 +1,21 @@ +driverName = 'sqlite'; + parent::setUp(); + } + + function testAutoQuoting() + { + $db = $this->getConnection(false); + + $sql = 'SELECT [[id]], [[t.name]] FROM {{tbl_customer}} t'; + $command = $db->createCommand($sql); + $this->assertEquals("SELECT \"id\", 't'.\"name\" FROM 'tbl_customer' t", $command->sql); + } +} diff --git a/tests/unit/framework/db/sqlite/SqliteConnectionTest.php b/tests/unit/framework/db/sqlite/SqliteConnectionTest.php new file mode 100644 index 0000000..eeb5aae --- /dev/null +++ b/tests/unit/framework/db/sqlite/SqliteConnectionTest.php @@ -0,0 +1,47 @@ +driverName = 'sqlite'; + parent::setUp(); + } + + function testConstruct() + { + $connection = $this->getConnection(false); + $params = $this->database; + + $this->assertEquals($params['dsn'], $connection->dsn); + } + + function testQuoteValue() + { + $connection = $this->getConnection(false); + $this->assertEquals(123, $connection->quoteValue(123)); + $this->assertEquals("'string'", $connection->quoteValue('string')); + $this->assertEquals("'It''s interesting'", $connection->quoteValue("It's interesting")); + } + + function testQuoteTableName() + { + $connection = $this->getConnection(false); + $this->assertEquals("'table'", $connection->quoteTableName('table')); + $this->assertEquals("'schema'.'table'", $connection->quoteTableName('schema.table')); + $this->assertEquals('{{table}}', $connection->quoteTableName('{{table}}')); + $this->assertEquals('(table)', $connection->quoteTableName('(table)')); + } + + function testQuoteColumnName() + { + $connection = $this->getConnection(false); + $this->assertEquals('"column"', $connection->quoteColumnName('column')); + $this->assertEquals("'table'.\"column\"", $connection->quoteColumnName('table.column')); + $this->assertEquals('[[column]]', $connection->quoteColumnName('[[column]]')); + $this->assertEquals('{{column}}', $connection->quoteColumnName('{{column}}')); + $this->assertEquals('(column)', $connection->quoteColumnName('(column)')); + } +} diff --git a/tests/unit/framework/db/sqlite/SqliteQueryTest.php b/tests/unit/framework/db/sqlite/SqliteQueryTest.php new file mode 100644 index 0000000..f00e59e --- /dev/null +++ b/tests/unit/framework/db/sqlite/SqliteQueryTest.php @@ -0,0 +1,20 @@ +driverName = 'sqlite'; + parent::setUp(); + } +} diff --git a/tests/unit/framework/helpers/ArrayHelperTest.php b/tests/unit/framework/helpers/ArrayHelperTest.php index b3ffabf..8c83278 100644 --- a/tests/unit/framework/helpers/ArrayHelperTest.php +++ b/tests/unit/framework/helpers/ArrayHelperTest.php @@ -12,6 +12,16 @@ class ArrayHelperTest extends \yii\test\TestCase } + public function testRemove() + { + $array = array('name' => 'b', 'age' => 3); + $name = ArrayHelper::remove($array, 'name'); + + $this->assertEquals($name, 'b'); + $this->assertEquals($array, array('age' => 3)); + } + + public function testMultisort() { // single key diff --git a/tests/unit/framework/helpers/StringHelperTest.php b/tests/unit/framework/helpers/StringHelperTest.php index c37aafd..64811d1 100644 --- a/tests/unit/framework/helpers/StringHelperTest.php +++ b/tests/unit/framework/helpers/StringHelperTest.php @@ -70,4 +70,48 @@ class StringHelperTest extends \yii\test\TestCase $this->assertEquals('PostTag', StringHelper::id2camel('post-tag')); $this->assertEquals('PostTag', StringHelper::id2camel('post_tag', '_')); } + + public function testBasename() + { + $this->assertEquals('', StringHelper::basename('')); + + $this->assertEquals('file', StringHelper::basename('file')); + $this->assertEquals('file.test', StringHelper::basename('file.test', '.test2')); + $this->assertEquals('file', StringHelper::basename('file.test', '.test')); + + $this->assertEquals('file', StringHelper::basename('/file')); + $this->assertEquals('file.test', StringHelper::basename('/file.test', '.test2')); + $this->assertEquals('file', StringHelper::basename('/file.test', '.test')); + + $this->assertEquals('file', StringHelper::basename('/path/to/file')); + $this->assertEquals('file.test', StringHelper::basename('/path/to/file.test', '.test2')); + $this->assertEquals('file', StringHelper::basename('/path/to/file.test', '.test')); + + $this->assertEquals('file', StringHelper::basename('\file')); + $this->assertEquals('file.test', StringHelper::basename('\file.test', '.test2')); + $this->assertEquals('file', StringHelper::basename('\file.test', '.test')); + + $this->assertEquals('file', StringHelper::basename('C:\file')); + $this->assertEquals('file.test', StringHelper::basename('C:\file.test', '.test2')); + $this->assertEquals('file', StringHelper::basename('C:\file.test', '.test')); + + $this->assertEquals('file', StringHelper::basename('C:\path\to\file')); + $this->assertEquals('file.test', StringHelper::basename('C:\path\to\file.test', '.test2')); + $this->assertEquals('file', StringHelper::basename('C:\path\to\file.test', '.test')); + + // mixed paths + $this->assertEquals('file.test', StringHelper::basename('/path\to/file.test')); + $this->assertEquals('file.test', StringHelper::basename('/path/to\file.test')); + $this->assertEquals('file.test', StringHelper::basename('\path/to\file.test')); + + // \ and / in suffix + $this->assertEquals('file', StringHelper::basename('/path/to/filete/st', 'te/st')); + $this->assertEquals('st', StringHelper::basename('/path/to/filete/st', 'te\st')); + $this->assertEquals('file', StringHelper::basename('/path/to/filete\st', 'te\st')); + $this->assertEquals('st', StringHelper::basename('/path/to/filete\st', 'te/st')); + + // http://www.php.net/manual/en/function.basename.php#72254 + $this->assertEquals('foo', StringHelper::basename('/bar/foo/')); + $this->assertEquals('foo', StringHelper::basename('\\bar\\foo\\')); + } } diff --git a/tests/web/app/index.php b/tests/web/app/index.php index 4cfa1ab..7096665 100644 --- a/tests/web/app/index.php +++ b/tests/web/app/index.php @@ -1,6 +1,6 @@ run(); diff --git a/framework/.htaccess b/yii/.htaccess similarity index 100% rename from framework/.htaccess rename to yii/.htaccess diff --git a/framework/yii.php b/yii/Yii.php similarity index 100% rename from framework/yii.php rename to yii/Yii.php diff --git a/framework/YiiBase.php b/yii/YiiBase.php similarity index 98% rename from framework/YiiBase.php rename to yii/YiiBase.php index aeed6f5..1a3f50c 100644 --- a/framework/YiiBase.php +++ b/yii/YiiBase.php @@ -158,8 +158,8 @@ class YiiBase { foreach ($namespaces as $name => $path) { if ($name !== '') { - $name = '@' . str_replace('\\', '/', $name); - static::setAlias($name, $path); + $name = trim(strtr($name, array('\\' => '/', '_' => '/')), '/'); + static::setAlias('@' . $name, rtrim($path, '/\\') . '/' . $name); } } } @@ -370,7 +370,8 @@ class YiiBase include($classFile); - if (class_exists($className, false) || interface_exists($className, false)) { + if (class_exists($className, false) || interface_exists($className, false) || + function_exists('trait_exists') && trait_exists($className, false)) { return true; } else { throw new UnknownClassException("Unable to find '$className' in file: $classFile"); diff --git a/framework/assets.php b/yii/assets.php similarity index 66% rename from framework/assets.php rename to yii/assets.php index 919011b..7ee177d 100644 --- a/framework/assets.php +++ b/yii/assets.php @@ -28,4 +28,18 @@ return array( ), 'depends' => array('yii', 'yii/validation'), ), + 'yii/captcha' => array( + 'sourcePath' => __DIR__ . '/assets', + 'js' => array( + 'yii.captcha.js', + ), + 'depends' => array('yii'), + ), + 'yii/debug' => array( + 'sourcePath' => __DIR__ . '/assets', + 'js' => array( + 'yii.debug.js', + ), + 'depends' => array('yii'), + ), ); diff --git a/framework/assets/jquery.min.js b/yii/assets/jquery.min.js similarity index 100% rename from framework/assets/jquery.min.js rename to yii/assets/jquery.min.js diff --git a/framework/assets/yii.activeForm.js b/yii/assets/yii.activeForm.js similarity index 99% rename from framework/assets/yii.activeForm.js rename to yii/assets/yii.activeForm.js index 158ea74..d987879 100644 --- a/framework/assets/yii.activeForm.js +++ b/yii/assets/yii.activeForm.js @@ -116,8 +116,8 @@ }); }, - options: function() { - return this.data('yiiActiveForm').settings; + data: function() { + return this.data('yiiActiveForm'); }, submitForm: function () { @@ -384,4 +384,4 @@ } }; -})(window.jQuery); \ No newline at end of file +})(window.jQuery); diff --git a/yii/assets/yii.captcha.js b/yii/assets/yii.captcha.js new file mode 100644 index 0000000..9211edb --- /dev/null +++ b/yii/assets/yii.captcha.js @@ -0,0 +1,72 @@ +/** + * Yii Captcha widget. + * + * This is the JavaScript widget used by the yii\widgets\Captcha widget. + * + * @link http://www.yiiframework.com/ + * @copyright Copyright (c) 2008 Yii Software LLC + * @license http://www.yiiframework.com/license/ + * @author Qiang Xue + * @since 2.0 + */ +(function ($) { + $.fn.yiiCaptcha = function (method) { + if (methods[method]) { + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + } else if (typeof method === 'object' || !method) { + return methods.init.apply(this, arguments); + } else { + $.error('Method ' + method + ' does not exist on jQuery.yiiCaptcha'); + return false; + } + }; + + var defaults = { + refreshUrl: undefined, + hashKey: undefined + }; + + var methods = { + init: function (options) { + return this.each(function () { + var $e = $(this); + var settings = $.extend({}, defaults, options || {}); + $e.data('yiiCaptcha', { + settings: settings + }); + + $e.on('click.yiiCaptcha', function() { + methods.refresh.apply($e); + return false; + }); + + }); + }, + + refresh: function () { + var $e = this, + settings = this.data('yiiCaptcha').settings; + $.ajax({ + url: $e.data('yiiCaptcha').settings.refreshUrl, + dataType: 'json', + cache: false, + success: function(data) { + $e.attr('src', data['url']); + $('body').data(settings.hashKey, [data['hash1'], data['hash2']]); + } + }); + }, + + destroy: function () { + return this.each(function () { + $(window).unbind('.yiiCaptcha'); + $(this).removeData('yiiCaptcha'); + }); + }, + + data: function() { + return this.data('yiiCaptcha'); + } + }; +})(window.jQuery); + diff --git a/yii/assets/yii.debug.js b/yii/assets/yii.debug.js new file mode 100644 index 0000000..4e32d89 --- /dev/null +++ b/yii/assets/yii.debug.js @@ -0,0 +1,26 @@ +/** + * Yii debug module. + * + * This JavaScript module provides the functions needed by the Yii debug toolbar. + * + * @link http://www.yiiframework.com/ + * @copyright Copyright (c) 2008 Yii Software LLC + * @license http://www.yiiframework.com/license/ + * @author Qiang Xue + * @since 2.0 + */ + +yii.debug = (function ($) { + return { + load: function (id, url) { + $.ajax({ + url: url, + //dataType: 'json', + success: function(data) { + var $e = $('#' + id); + $e.html(data); + } + }); + } + }; +})(jQuery); diff --git a/framework/assets/yii.js b/yii/assets/yii.js similarity index 100% rename from framework/assets/yii.js rename to yii/assets/yii.js diff --git a/framework/assets/yii.validation.js b/yii/assets/yii.validation.js similarity index 99% rename from framework/assets/yii.validation.js rename to yii/assets/yii.validation.js index fd098be..5fa8492 100644 --- a/framework/assets/yii.validation.js +++ b/yii/assets/yii.validation.js @@ -1,7 +1,7 @@ /** * Yii validation module. * - * This JavaScript module provides the validation methods for the built-in validaotrs. + * This JavaScript module provides the validation methods for the built-in validators. * * @link http://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC diff --git a/framework/base/Action.php b/yii/base/Action.php similarity index 100% rename from framework/base/Action.php rename to yii/base/Action.php diff --git a/framework/base/ActionEvent.php b/yii/base/ActionEvent.php similarity index 100% rename from framework/base/ActionEvent.php rename to yii/base/ActionEvent.php diff --git a/framework/base/ActionFilter.php b/yii/base/ActionFilter.php similarity index 100% rename from framework/base/ActionFilter.php rename to yii/base/ActionFilter.php diff --git a/framework/base/Application.php b/yii/base/Application.php similarity index 100% rename from framework/base/Application.php rename to yii/base/Application.php diff --git a/framework/base/Behavior.php b/yii/base/Behavior.php similarity index 100% rename from framework/base/Behavior.php rename to yii/base/Behavior.php diff --git a/framework/base/Component.php b/yii/base/Component.php similarity index 100% rename from framework/base/Component.php rename to yii/base/Component.php diff --git a/framework/base/Controller.php b/yii/base/Controller.php similarity index 99% rename from framework/base/Controller.php rename to yii/base/Controller.php index 9572636..3b16a93 100644 --- a/framework/base/Controller.php +++ b/yii/base/Controller.php @@ -203,7 +203,7 @@ class Controller extends Component public function forward($route, $params = array()) { $status = $this->run($route, $params); - exit($status); + Yii::$app->end($status); } /** diff --git a/framework/base/Dictionary.php b/yii/base/Dictionary.php similarity index 100% rename from framework/base/Dictionary.php rename to yii/base/Dictionary.php diff --git a/framework/base/DictionaryIterator.php b/yii/base/DictionaryIterator.php similarity index 100% rename from framework/base/DictionaryIterator.php rename to yii/base/DictionaryIterator.php diff --git a/framework/base/ErrorException.php b/yii/base/ErrorException.php similarity index 100% rename from framework/base/ErrorException.php rename to yii/base/ErrorException.php diff --git a/framework/base/ErrorHandler.php b/yii/base/ErrorHandler.php similarity index 100% rename from framework/base/ErrorHandler.php rename to yii/base/ErrorHandler.php diff --git a/framework/base/Event.php b/yii/base/Event.php similarity index 100% rename from framework/base/Event.php rename to yii/base/Event.php diff --git a/framework/base/Exception.php b/yii/base/Exception.php similarity index 100% rename from framework/base/Exception.php rename to yii/base/Exception.php diff --git a/framework/base/HttpException.php b/yii/base/HttpException.php similarity index 100% rename from framework/base/HttpException.php rename to yii/base/HttpException.php diff --git a/framework/base/InlineAction.php b/yii/base/InlineAction.php similarity index 100% rename from framework/base/InlineAction.php rename to yii/base/InlineAction.php diff --git a/framework/base/InvalidCallException.php b/yii/base/InvalidCallException.php similarity index 100% rename from framework/base/InvalidCallException.php rename to yii/base/InvalidCallException.php diff --git a/framework/base/InvalidConfigException.php b/yii/base/InvalidConfigException.php similarity index 100% rename from framework/base/InvalidConfigException.php rename to yii/base/InvalidConfigException.php diff --git a/framework/base/InvalidParamException.php b/yii/base/InvalidParamException.php similarity index 100% rename from framework/base/InvalidParamException.php rename to yii/base/InvalidParamException.php diff --git a/framework/base/InvalidRequestException.php b/yii/base/InvalidRequestException.php similarity index 100% rename from framework/base/InvalidRequestException.php rename to yii/base/InvalidRequestException.php diff --git a/framework/base/InvalidRouteException.php b/yii/base/InvalidRouteException.php similarity index 100% rename from framework/base/InvalidRouteException.php rename to yii/base/InvalidRouteException.php diff --git a/framework/base/Model.php b/yii/base/Model.php similarity index 100% rename from framework/base/Model.php rename to yii/base/Model.php diff --git a/framework/base/ModelEvent.php b/yii/base/ModelEvent.php similarity index 100% rename from framework/base/ModelEvent.php rename to yii/base/ModelEvent.php diff --git a/framework/base/Module.php b/yii/base/Module.php similarity index 100% rename from framework/base/Module.php rename to yii/base/Module.php diff --git a/framework/base/NotSupportedException.php b/yii/base/NotSupportedException.php similarity index 100% rename from framework/base/NotSupportedException.php rename to yii/base/NotSupportedException.php diff --git a/framework/base/Object.php b/yii/base/Object.php similarity index 100% rename from framework/base/Object.php rename to yii/base/Object.php diff --git a/framework/base/Request.php b/yii/base/Request.php similarity index 100% rename from framework/base/Request.php rename to yii/base/Request.php diff --git a/framework/base/Response.php b/yii/base/Response.php similarity index 100% rename from framework/base/Response.php rename to yii/base/Response.php diff --git a/framework/base/Theme.php b/yii/base/Theme.php similarity index 100% rename from framework/base/Theme.php rename to yii/base/Theme.php diff --git a/framework/base/UnknownClassException.php b/yii/base/UnknownClassException.php similarity index 100% rename from framework/base/UnknownClassException.php rename to yii/base/UnknownClassException.php diff --git a/framework/base/UnknownMethodException.php b/yii/base/UnknownMethodException.php similarity index 100% rename from framework/base/UnknownMethodException.php rename to yii/base/UnknownMethodException.php diff --git a/framework/base/UnknownPropertyException.php b/yii/base/UnknownPropertyException.php similarity index 100% rename from framework/base/UnknownPropertyException.php rename to yii/base/UnknownPropertyException.php diff --git a/framework/base/UserException.php b/yii/base/UserException.php similarity index 100% rename from framework/base/UserException.php rename to yii/base/UserException.php diff --git a/framework/base/Vector.php b/yii/base/Vector.php similarity index 100% rename from framework/base/Vector.php rename to yii/base/Vector.php diff --git a/framework/base/VectorIterator.php b/yii/base/VectorIterator.php similarity index 100% rename from framework/base/VectorIterator.php rename to yii/base/VectorIterator.php diff --git a/framework/base/View.php b/yii/base/View.php similarity index 98% rename from framework/base/View.php rename to yii/base/View.php index af1f0d5..af65c49 100644 --- a/framework/base/View.php +++ b/yii/base/View.php @@ -23,6 +23,14 @@ use yii\helpers\Html; class View extends Component { /** + * @event ViewEvent an event that is triggered by [[beginPage()]]. + */ + const EVENT_BEGIN_PAGE = 'beginPage'; + /** + * @event ViewEvent an event that is triggered by [[endPage()]]. + */ + const EVENT_END_PAGE = 'endPage'; + /** * @event ViewEvent an event that is triggered by [[renderFile()]] right before it renders a view file. */ const EVENT_BEFORE_RENDER = 'beforeRender'; @@ -555,6 +563,8 @@ class View extends Component { ob_start(); ob_implicit_flush(false); + + $this->trigger(self::EVENT_BEGIN_PAGE); } /** @@ -562,6 +572,8 @@ class View extends Component */ public function endPage() { + $this->trigger(self::EVENT_END_PAGE); + $content = ob_get_clean(); echo strtr($content, array( self::PL_HEAD => $this->renderHeadHtml(), diff --git a/framework/base/ViewEvent.php b/yii/base/ViewEvent.php similarity index 100% rename from framework/base/ViewEvent.php rename to yii/base/ViewEvent.php diff --git a/framework/base/ViewRenderer.php b/yii/base/ViewRenderer.php similarity index 100% rename from framework/base/ViewRenderer.php rename to yii/base/ViewRenderer.php diff --git a/framework/base/Widget.php b/yii/base/Widget.php similarity index 100% rename from framework/base/Widget.php rename to yii/base/Widget.php diff --git a/framework/caching/ApcCache.php b/yii/caching/ApcCache.php similarity index 100% rename from framework/caching/ApcCache.php rename to yii/caching/ApcCache.php diff --git a/framework/caching/Cache.php b/yii/caching/Cache.php similarity index 100% rename from framework/caching/Cache.php rename to yii/caching/Cache.php diff --git a/framework/caching/ChainedDependency.php b/yii/caching/ChainedDependency.php similarity index 100% rename from framework/caching/ChainedDependency.php rename to yii/caching/ChainedDependency.php diff --git a/framework/caching/DbCache.php b/yii/caching/DbCache.php similarity index 100% rename from framework/caching/DbCache.php rename to yii/caching/DbCache.php diff --git a/framework/caching/DbDependency.php b/yii/caching/DbDependency.php similarity index 100% rename from framework/caching/DbDependency.php rename to yii/caching/DbDependency.php diff --git a/framework/caching/Dependency.php b/yii/caching/Dependency.php similarity index 100% rename from framework/caching/Dependency.php rename to yii/caching/Dependency.php diff --git a/framework/caching/DummyCache.php b/yii/caching/DummyCache.php similarity index 100% rename from framework/caching/DummyCache.php rename to yii/caching/DummyCache.php diff --git a/framework/caching/ExpressionDependency.php b/yii/caching/ExpressionDependency.php similarity index 100% rename from framework/caching/ExpressionDependency.php rename to yii/caching/ExpressionDependency.php diff --git a/framework/caching/FileCache.php b/yii/caching/FileCache.php similarity index 100% rename from framework/caching/FileCache.php rename to yii/caching/FileCache.php diff --git a/framework/caching/FileDependency.php b/yii/caching/FileDependency.php similarity index 100% rename from framework/caching/FileDependency.php rename to yii/caching/FileDependency.php diff --git a/framework/caching/MemCache.php b/yii/caching/MemCache.php similarity index 100% rename from framework/caching/MemCache.php rename to yii/caching/MemCache.php diff --git a/framework/caching/MemCacheServer.php b/yii/caching/MemCacheServer.php similarity index 100% rename from framework/caching/MemCacheServer.php rename to yii/caching/MemCacheServer.php diff --git a/framework/caching/WinCache.php b/yii/caching/WinCache.php similarity index 100% rename from framework/caching/WinCache.php rename to yii/caching/WinCache.php diff --git a/framework/caching/XCache.php b/yii/caching/XCache.php similarity index 100% rename from framework/caching/XCache.php rename to yii/caching/XCache.php diff --git a/framework/caching/ZendDataCache.php b/yii/caching/ZendDataCache.php similarity index 100% rename from framework/caching/ZendDataCache.php rename to yii/caching/ZendDataCache.php diff --git a/framework/console/Application.php b/yii/console/Application.php similarity index 100% rename from framework/console/Application.php rename to yii/console/Application.php diff --git a/framework/console/Controller.php b/yii/console/Controller.php similarity index 100% rename from framework/console/Controller.php rename to yii/console/Controller.php diff --git a/framework/console/Exception.php b/yii/console/Exception.php similarity index 100% rename from framework/console/Exception.php rename to yii/console/Exception.php diff --git a/framework/console/Request.php b/yii/console/Request.php similarity index 100% rename from framework/console/Request.php rename to yii/console/Request.php diff --git a/framework/console/controllers/AppController.php b/yii/console/controllers/AppController.php similarity index 100% rename from framework/console/controllers/AppController.php rename to yii/console/controllers/AppController.php diff --git a/framework/console/controllers/AssetController.php b/yii/console/controllers/AssetController.php similarity index 100% rename from framework/console/controllers/AssetController.php rename to yii/console/controllers/AssetController.php diff --git a/framework/console/controllers/CacheController.php b/yii/console/controllers/CacheController.php similarity index 100% rename from framework/console/controllers/CacheController.php rename to yii/console/controllers/CacheController.php diff --git a/framework/console/controllers/HelpController.php b/yii/console/controllers/HelpController.php similarity index 100% rename from framework/console/controllers/HelpController.php rename to yii/console/controllers/HelpController.php diff --git a/framework/console/controllers/MessageController.php b/yii/console/controllers/MessageController.php similarity index 100% rename from framework/console/controllers/MessageController.php rename to yii/console/controllers/MessageController.php diff --git a/framework/console/controllers/MigrateController.php b/yii/console/controllers/MigrateController.php similarity index 100% rename from framework/console/controllers/MigrateController.php rename to yii/console/controllers/MigrateController.php diff --git a/framework/console/runtime/.gitignore b/yii/console/runtime/.gitignore similarity index 100% rename from framework/console/runtime/.gitignore rename to yii/console/runtime/.gitignore diff --git a/framework/db/ActiveQuery.php b/yii/db/ActiveQuery.php similarity index 100% rename from framework/db/ActiveQuery.php rename to yii/db/ActiveQuery.php diff --git a/framework/db/ActiveRecord.php b/yii/db/ActiveRecord.php similarity index 99% rename from framework/db/ActiveRecord.php rename to yii/db/ActiveRecord.php index bf1f622..356819d 100644 --- a/framework/db/ActiveRecord.php +++ b/yii/db/ActiveRecord.php @@ -28,7 +28,7 @@ use yii\helpers\StringHelper; * @property TableSchema $tableSchema the schema information of the DB table associated with this AR class. * @property array $oldAttributes the old attribute values (name-value pairs). * @property array $dirtyAttributes the changed attribute values (name-value pairs). - * @property boolean $isPrimaryKey whether the record is new and should be inserted when calling [[save()]]. + * @property boolean $isNewRecord whether the record is new and should be inserted when calling [[save()]]. * @property mixed $primaryKey the primary key value. * @property mixed $oldPrimaryKey the old primary key value. * @@ -252,7 +252,7 @@ class ActiveRecord extends Model */ public static function tableName() { - return 'tbl_' . StringHelper::camel2id(basename(get_called_class()), '_'); + return 'tbl_' . StringHelper::camel2id(StringHelper::basename(get_called_class()), '_'); } /** diff --git a/framework/db/ActiveRelation.php b/yii/db/ActiveRelation.php similarity index 99% rename from framework/db/ActiveRelation.php rename to yii/db/ActiveRelation.php index 97e2a8c..42ae0e7 100644 --- a/framework/db/ActiveRelation.php +++ b/yii/db/ActiveRelation.php @@ -131,7 +131,7 @@ class ActiveRelation extends ActiveQuery /** * Finds the related records and populates them into the primary models. - * This method is internally by [[ActiveQuery]]. Do not call it directly. + * This method is internally used by [[ActiveQuery]]. Do not call it directly. * @param string $name the relation name * @param array $primaryModels primary models * @return array the related models diff --git a/framework/db/ColumnSchema.php b/yii/db/ColumnSchema.php similarity index 100% rename from framework/db/ColumnSchema.php rename to yii/db/ColumnSchema.php diff --git a/framework/db/Command.php b/yii/db/Command.php similarity index 100% rename from framework/db/Command.php rename to yii/db/Command.php diff --git a/framework/db/Connection.php b/yii/db/Connection.php similarity index 99% rename from framework/db/Connection.php rename to yii/db/Connection.php index 03b10a8..37a5307 100644 --- a/framework/db/Connection.php +++ b/yii/db/Connection.php @@ -242,7 +242,7 @@ class Connection extends Component 'mysql' => 'yii\db\mysql\Schema', // MySQL 'sqlite' => 'yii\db\sqlite\Schema', // sqlite 3 'sqlite2' => 'yii\db\sqlite\Schema', // sqlite 2 - 'mssql' => 'yi\db\dao\mssql\Schema', // Mssql driver on windows hosts + 'mssql' => 'yii\db\dao\mssql\Schema', // Mssql driver on windows hosts 'sqlsrv' => 'yii\db\mssql\Schema', // Mssql 'oci' => 'yii\db\oci\Schema', // Oracle driver 'dblib' => 'yii\db\mssql\Schema', // dblib drivers on linux (and maybe others os) hosts diff --git a/framework/db/DataReader.php b/yii/db/DataReader.php similarity index 100% rename from framework/db/DataReader.php rename to yii/db/DataReader.php diff --git a/framework/db/Exception.php b/yii/db/Exception.php similarity index 100% rename from framework/db/Exception.php rename to yii/db/Exception.php diff --git a/framework/db/Expression.php b/yii/db/Expression.php similarity index 100% rename from framework/db/Expression.php rename to yii/db/Expression.php diff --git a/framework/db/Migration.php b/yii/db/Migration.php similarity index 100% rename from framework/db/Migration.php rename to yii/db/Migration.php diff --git a/framework/db/Query.php b/yii/db/Query.php similarity index 100% rename from framework/db/Query.php rename to yii/db/Query.php diff --git a/framework/db/QueryBuilder.php b/yii/db/QueryBuilder.php similarity index 100% rename from framework/db/QueryBuilder.php rename to yii/db/QueryBuilder.php diff --git a/framework/db/Schema.php b/yii/db/Schema.php similarity index 100% rename from framework/db/Schema.php rename to yii/db/Schema.php diff --git a/framework/db/StaleObjectException.php b/yii/db/StaleObjectException.php similarity index 100% rename from framework/db/StaleObjectException.php rename to yii/db/StaleObjectException.php diff --git a/framework/db/TableSchema.php b/yii/db/TableSchema.php similarity index 100% rename from framework/db/TableSchema.php rename to yii/db/TableSchema.php diff --git a/framework/db/Transaction.php b/yii/db/Transaction.php similarity index 100% rename from framework/db/Transaction.php rename to yii/db/Transaction.php diff --git a/framework/db/mysql/QueryBuilder.php b/yii/db/mysql/QueryBuilder.php similarity index 100% rename from framework/db/mysql/QueryBuilder.php rename to yii/db/mysql/QueryBuilder.php diff --git a/framework/db/mysql/Schema.php b/yii/db/mysql/Schema.php similarity index 100% rename from framework/db/mysql/Schema.php rename to yii/db/mysql/Schema.php diff --git a/framework/db/sqlite/QueryBuilder.php b/yii/db/sqlite/QueryBuilder.php similarity index 100% rename from framework/db/sqlite/QueryBuilder.php rename to yii/db/sqlite/QueryBuilder.php diff --git a/framework/db/sqlite/Schema.php b/yii/db/sqlite/Schema.php similarity index 98% rename from framework/db/sqlite/Schema.php rename to yii/db/sqlite/Schema.php index 45f8392..d4fb245 100644 --- a/framework/db/sqlite/Schema.php +++ b/yii/db/sqlite/Schema.php @@ -169,7 +169,7 @@ class Schema extends \yii\db\Schema } } } - $column->phpType = $this->getColumnPhpType($this->type); + $column->phpType = $this->getColumnPhpType($column); $value = $info['dflt_value']; if ($column->type === 'string') { diff --git a/yii/debug/Module.php b/yii/debug/Module.php new file mode 100644 index 0000000..3421d95 --- /dev/null +++ b/yii/debug/Module.php @@ -0,0 +1,17 @@ + + * @since 2.0 + */ +class Module extends \yii\base\Module +{ + public $controllerNamespace = 'yii\debug\controllers'; +} \ No newline at end of file diff --git a/yii/debug/Toolbar.php b/yii/debug/Toolbar.php new file mode 100644 index 0000000..84b55c8 --- /dev/null +++ b/yii/debug/Toolbar.php @@ -0,0 +1,38 @@ + + * @since 2.0 + */ +class Toolbar extends Widget +{ + public $debugAction = 'debug'; + public $enabled = YII_DEBUG; + + public function run() + { + if ($this->enabled) { + $id = 'yii-debug-toolbar'; + $url = Yii::$app->getUrlManager()->createUrl($this->debugAction, array( + 'tag' => Yii::getLogger()->tag, + )); + $this->view->registerJs("yii.debug.load('$id', '$url');"); + $this->view->registerAssetBundle('yii/debug'); + echo Html::tag('div', '', array( + 'id' => $id, + 'style' => 'display: none', + )); + } + } +} diff --git a/yii/debug/controllers/DefaultController.php b/yii/debug/controllers/DefaultController.php new file mode 100644 index 0000000..ca90920 --- /dev/null +++ b/yii/debug/controllers/DefaultController.php @@ -0,0 +1,22 @@ + + * @since 2.0 + */ +class DefaultController extends Controller +{ + public function actionIndex($tag) + { + echo $tag; + } +} \ No newline at end of file diff --git a/framework/helpers/ArrayHelper.php b/yii/helpers/ArrayHelper.php similarity index 100% rename from framework/helpers/ArrayHelper.php rename to yii/helpers/ArrayHelper.php diff --git a/framework/helpers/Console.php b/yii/helpers/Console.php similarity index 100% rename from framework/helpers/Console.php rename to yii/helpers/Console.php diff --git a/framework/helpers/FileHelper.php b/yii/helpers/FileHelper.php similarity index 100% rename from framework/helpers/FileHelper.php rename to yii/helpers/FileHelper.php diff --git a/framework/helpers/Html.php b/yii/helpers/Html.php similarity index 100% rename from framework/helpers/Html.php rename to yii/helpers/Html.php diff --git a/framework/helpers/Json.php b/yii/helpers/Json.php similarity index 100% rename from framework/helpers/Json.php rename to yii/helpers/Json.php diff --git a/framework/helpers/Markdown.php b/yii/helpers/Markdown.php similarity index 100% rename from framework/helpers/Markdown.php rename to yii/helpers/Markdown.php diff --git a/framework/helpers/Purifier.php b/yii/helpers/Purifier.php similarity index 100% rename from framework/helpers/Purifier.php rename to yii/helpers/Purifier.php diff --git a/framework/helpers/SecurityHelper.php b/yii/helpers/SecurityHelper.php similarity index 100% rename from framework/helpers/SecurityHelper.php rename to yii/helpers/SecurityHelper.php diff --git a/framework/helpers/StringHelper.php b/yii/helpers/StringHelper.php similarity index 100% rename from framework/helpers/StringHelper.php rename to yii/helpers/StringHelper.php diff --git a/framework/helpers/VarDumper.php b/yii/helpers/VarDumper.php similarity index 100% rename from framework/helpers/VarDumper.php rename to yii/helpers/VarDumper.php diff --git a/framework/helpers/base/ArrayHelper.php b/yii/helpers/base/ArrayHelper.php similarity index 92% rename from framework/helpers/base/ArrayHelper.php rename to yii/helpers/base/ArrayHelper.php index 672c7b9..e482883 100644 --- a/framework/helpers/base/ArrayHelper.php +++ b/yii/helpers/base/ArrayHelper.php @@ -87,6 +87,35 @@ class ArrayHelper } /** + * Removes an item from an array and returns the value. If the key does not exist in the array, the default value + * will be returned instead. + * + * Usage examples, + * + * ~~~ + * // $array = array('type'=>'A', 'options'=>array(1,2)); + * // working with array + * $type = \yii\helpers\ArrayHelper::remove($array, 'type'); + * // $array content + * // $array = array('options'=>array(1,2)); + * ~~~ + * + * @param array $array the array to extract value from + * @param string $key key name of the array element + * @param mixed $default the default value to be returned if the specified key does not exist + * @return mixed|null the value of the element if found, default value otherwise + */ + public static function remove(&$array, $key, $default = null) + { + if (is_array($array) && (isset($array[$key]) || array_key_exists($key, $array))) { + $value = $array[$key]; + unset($array[$key]); + return $value; + } + return $default; + } + + /** * Indexes an array according to a specified key. * The input array should be multidimensional or an array of objects. * @@ -284,7 +313,7 @@ class ArrayHelper $args[] = $column; } } else { - $args[] = static::getColumn($array, $key); + $args[] = static::getColumn($array, $key); } $args[] = $ascending[$i] ? SORT_ASC : SORT_DESC; $args[] = $flag; diff --git a/framework/helpers/base/Console.php b/yii/helpers/base/Console.php similarity index 90% rename from framework/helpers/base/Console.php rename to yii/helpers/base/Console.php index 3c7dc0b..b611919 100644 --- a/framework/helpers/base/Console.php +++ b/yii/helpers/base/Console.php @@ -316,76 +316,76 @@ class Console $styleA = array(); foreach (explode(';', $ansi) as $controlCode) { switch ($controlCode) { - case static::FG_BLACK: + case self::FG_BLACK: $style = array('color' => '#000000'); break; - case static::FG_BLUE: + case self::FG_BLUE: $style = array('color' => '#000078'); break; - case static::FG_CYAN: + case self::FG_CYAN: $style = array('color' => '#007878'); break; - case static::FG_GREEN: + case self::FG_GREEN: $style = array('color' => '#007800'); break; - case static::FG_GREY: + case self::FG_GREY: $style = array('color' => '#787878'); break; - case static::FG_PURPLE: + case self::FG_PURPLE: $style = array('color' => '#780078'); break; - case static::FG_RED: + case self::FG_RED: $style = array('color' => '#780000'); break; - case static::FG_YELLOW: + case self::FG_YELLOW: $style = array('color' => '#787800'); break; - case static::BG_BLACK: + case self::BG_BLACK: $style = array('background-color' => '#000000'); break; - case static::BG_BLUE: + case self::BG_BLUE: $style = array('background-color' => '#000078'); break; - case static::BG_CYAN: + case self::BG_CYAN: $style = array('background-color' => '#007878'); break; - case static::BG_GREEN: + case self::BG_GREEN: $style = array('background-color' => '#007800'); break; - case static::BG_GREY: + case self::BG_GREY: $style = array('background-color' => '#787878'); break; - case static::BG_PURPLE: + case self::BG_PURPLE: $style = array('background-color' => '#780078'); break; - case static::BG_RED: + case self::BG_RED: $style = array('background-color' => '#780000'); break; - case static::BG_YELLOW: + case self::BG_YELLOW: $style = array('background-color' => '#787800'); break; - case static::BOLD: + case self::BOLD: $style = array('font-weight' => 'bold'); break; - case static::ITALIC: + case self::ITALIC: $style = array('font-style' => 'italic'); break; - case static::UNDERLINE: + case self::UNDERLINE: $style = array('text-decoration' => array('underline')); break; - case static::OVERLINED: + case self::OVERLINED: $style = array('text-decoration' => array('overline')); break; - case static::CROSSED_OUT: + case self::CROSSED_OUT: $style = array('text-decoration' => array('line-through')); break; - case static::BLINK: + case self::BLINK: $style = array('text-decoration' => array('blink')); break; - case static::NEGATIVE: // ??? - case static::CONCEALED: - case static::ENCIRCLED: - case static::FRAMED: + case self::NEGATIVE: // ??? + case self::CONCEALED: + case self::ENCIRCLED: + case self::FRAMED: // TODO allow resetting codes break; case 0: // ansi reset @@ -456,39 +456,39 @@ class Console public static function renderColoredString($string, $colored = true) { static $conversions = array( - '%y' => array(static::FG_YELLOW), - '%g' => array(static::FG_GREEN), - '%b' => array(static::FG_BLUE), - '%r' => array(static::FG_RED), - '%p' => array(static::FG_PURPLE), - '%m' => array(static::FG_PURPLE), - '%c' => array(static::FG_CYAN), - '%w' => array(static::FG_GREY), - '%k' => array(static::FG_BLACK), + '%y' => array(self::FG_YELLOW), + '%g' => array(self::FG_GREEN), + '%b' => array(self::FG_BLUE), + '%r' => array(self::FG_RED), + '%p' => array(self::FG_PURPLE), + '%m' => array(self::FG_PURPLE), + '%c' => array(self::FG_CYAN), + '%w' => array(self::FG_GREY), + '%k' => array(self::FG_BLACK), '%n' => array(0), // reset - '%Y' => array(static::FG_YELLOW, static::BOLD), - '%G' => array(static::FG_GREEN, static::BOLD), - '%B' => array(static::FG_BLUE, static::BOLD), - '%R' => array(static::FG_RED, static::BOLD), - '%P' => array(static::FG_PURPLE, static::BOLD), - '%M' => array(static::FG_PURPLE, static::BOLD), - '%C' => array(static::FG_CYAN, static::BOLD), - '%W' => array(static::FG_GREY, static::BOLD), - '%K' => array(static::FG_BLACK, static::BOLD), - '%N' => array(0, static::BOLD), - '%3' => array(static::BG_YELLOW), - '%2' => array(static::BG_GREEN), - '%4' => array(static::BG_BLUE), - '%1' => array(static::BG_RED), - '%5' => array(static::BG_PURPLE), - '%6' => array(static::BG_PURPLE), - '%7' => array(static::BG_CYAN), - '%0' => array(static::BG_GREY), - '%F' => array(static::BLINK), - '%U' => array(static::UNDERLINE), - '%8' => array(static::NEGATIVE), - '%9' => array(static::BOLD), - '%_' => array(static::BOLD) + '%Y' => array(self::FG_YELLOW, self::BOLD), + '%G' => array(self::FG_GREEN, self::BOLD), + '%B' => array(self::FG_BLUE, self::BOLD), + '%R' => array(self::FG_RED, self::BOLD), + '%P' => array(self::FG_PURPLE, self::BOLD), + '%M' => array(self::FG_PURPLE, self::BOLD), + '%C' => array(self::FG_CYAN, self::BOLD), + '%W' => array(self::FG_GREY, self::BOLD), + '%K' => array(self::FG_BLACK, self::BOLD), + '%N' => array(0, self::BOLD), + '%3' => array(self::BG_YELLOW), + '%2' => array(self::BG_GREEN), + '%4' => array(self::BG_BLUE), + '%1' => array(self::BG_RED), + '%5' => array(self::BG_PURPLE), + '%6' => array(self::BG_PURPLE), + '%7' => array(self::BG_CYAN), + '%0' => array(self::BG_GREY), + '%F' => array(self::BLINK), + '%U' => array(self::UNDERLINE), + '%8' => array(self::NEGATIVE), + '%9' => array(self::BOLD), + '%_' => array(self::BOLD) ); if ($colored) { diff --git a/framework/helpers/base/FileHelper.php b/yii/helpers/base/FileHelper.php similarity index 100% rename from framework/helpers/base/FileHelper.php rename to yii/helpers/base/FileHelper.php diff --git a/framework/helpers/base/Html.php b/yii/helpers/base/Html.php similarity index 100% rename from framework/helpers/base/Html.php rename to yii/helpers/base/Html.php diff --git a/framework/helpers/base/Json.php b/yii/helpers/base/Json.php similarity index 100% rename from framework/helpers/base/Json.php rename to yii/helpers/base/Json.php diff --git a/framework/helpers/base/Markdown.php b/yii/helpers/base/Markdown.php similarity index 92% rename from framework/helpers/base/Markdown.php rename to yii/helpers/base/Markdown.php index 342c56b..1efdccb 100644 --- a/framework/helpers/base/Markdown.php +++ b/yii/helpers/base/Markdown.php @@ -7,7 +7,6 @@ namespace yii\helpers\base; -\Yii::setAlias('@Michelf', \Yii::getAlias('@yii/vendor/michelf/php-markdown/Michelf')); use Michelf\MarkdownExtra; /** diff --git a/framework/helpers/base/Purifier.php b/yii/helpers/base/Purifier.php similarity index 85% rename from framework/helpers/base/Purifier.php rename to yii/helpers/base/Purifier.php index 1342374..2c5d334 100644 --- a/framework/helpers/base/Purifier.php +++ b/yii/helpers/base/Purifier.php @@ -6,10 +6,6 @@ */ namespace yii\helpers\base; -if (!class_exists('HTMLPurifier_Bootstrap', false)) { - require_once(\Yii::getAlias('@yii/vendor/ezyang/htmlpurifier/library/HTMLPurifier.auto.php')); -} - /** * Purifier provides an ability to clean up HTML from any harmful code. * diff --git a/framework/helpers/base/SecurityHelper.php b/yii/helpers/base/SecurityHelper.php similarity index 100% rename from framework/helpers/base/SecurityHelper.php rename to yii/helpers/base/SecurityHelper.php diff --git a/framework/helpers/base/StringHelper.php b/yii/helpers/base/StringHelper.php similarity index 81% rename from framework/helpers/base/StringHelper.php rename to yii/helpers/base/StringHelper.php index cb4b09b..646bcbb 100644 --- a/framework/helpers/base/StringHelper.php +++ b/yii/helpers/base/StringHelper.php @@ -44,6 +44,29 @@ class StringHelper } /** + * Returns the trailing name component of a path. + * This method does the same as the php function basename() except that it will + * always use \ and / as directory separators, independent of the operating system. + * Note: basename() operates naively on the input string, and is not aware of the + * actual filesystem, or path components such as "..". + * @param string $path A path string. + * @param string $suffix If the name component ends in suffix this will also be cut off. + * @return string the trailing name component of the given path. + * @see http://www.php.net/manual/en/function.basename.php + */ + public static function basename($path, $suffix = '') + { + if (($len = mb_strlen($suffix)) > 0 && mb_substr($path, -$len) == $suffix) { + $path = mb_substr($path, 0, -$len); + } + $path = rtrim(str_replace('\\', '/', $path), '/\\'); + if (($pos = mb_strrpos($path, '/')) !== false) { + return mb_substr($path, $pos + 1); + } + return $path; + } + + /** * Converts a word to its plural form. * Note that this is for English only! * For example, 'apple' will become 'apples', and 'child' will become 'children'. diff --git a/framework/helpers/base/VarDumper.php b/yii/helpers/base/VarDumper.php similarity index 100% rename from framework/helpers/base/VarDumper.php rename to yii/helpers/base/VarDumper.php diff --git a/framework/helpers/base/mimeTypes.php b/yii/helpers/base/mimeTypes.php similarity index 100% rename from framework/helpers/base/mimeTypes.php rename to yii/helpers/base/mimeTypes.php diff --git a/framework/i18n/I18N.php b/yii/i18n/I18N.php similarity index 100% rename from framework/i18n/I18N.php rename to yii/i18n/I18N.php diff --git a/framework/i18n/MessageSource.php b/yii/i18n/MessageSource.php similarity index 100% rename from framework/i18n/MessageSource.php rename to yii/i18n/MessageSource.php diff --git a/framework/i18n/MissingTranslationEvent.php b/yii/i18n/MissingTranslationEvent.php similarity index 100% rename from framework/i18n/MissingTranslationEvent.php rename to yii/i18n/MissingTranslationEvent.php diff --git a/framework/i18n/PhpMessageSource.php b/yii/i18n/PhpMessageSource.php similarity index 100% rename from framework/i18n/PhpMessageSource.php rename to yii/i18n/PhpMessageSource.php diff --git a/framework/i18n/data/plurals.php b/yii/i18n/data/plurals.php similarity index 100% rename from framework/i18n/data/plurals.php rename to yii/i18n/data/plurals.php diff --git a/framework/i18n/data/plurals.xml b/yii/i18n/data/plurals.xml similarity index 100% rename from framework/i18n/data/plurals.xml rename to yii/i18n/data/plurals.xml diff --git a/framework/logging/DbTarget.php b/yii/logging/DbTarget.php similarity index 100% rename from framework/logging/DbTarget.php rename to yii/logging/DbTarget.php diff --git a/framework/logging/EmailTarget.php b/yii/logging/EmailTarget.php similarity index 100% rename from framework/logging/EmailTarget.php rename to yii/logging/EmailTarget.php diff --git a/framework/logging/FileTarget.php b/yii/logging/FileTarget.php similarity index 100% rename from framework/logging/FileTarget.php rename to yii/logging/FileTarget.php diff --git a/framework/logging/Logger.php b/yii/logging/Logger.php similarity index 97% rename from framework/logging/Logger.php rename to yii/logging/Logger.php index 5c9a89d..b557c5e 100644 --- a/framework/logging/Logger.php +++ b/yii/logging/Logger.php @@ -82,6 +82,11 @@ class Logger extends Component * @var Router the log target router registered with this logger. */ public $router; + /** + * @var string a tag that uniquely identifies the current request. This can be used + * to differentiate the log messages for different requests. + */ + public $tag; /** * Initializes the logger by registering [[flush()]] as a shutdown function. @@ -89,6 +94,7 @@ class Logger extends Component public function init() { parent::init(); + $this->tag = date('Ymd-His', microtime(true)); register_shutdown_function(array($this, 'flush'), true); } diff --git a/framework/logging/ProfileTarget.php b/yii/logging/ProfileTarget.php similarity index 100% rename from framework/logging/ProfileTarget.php rename to yii/logging/ProfileTarget.php diff --git a/framework/logging/Router.php b/yii/logging/Router.php similarity index 100% rename from framework/logging/Router.php rename to yii/logging/Router.php diff --git a/framework/logging/Target.php b/yii/logging/Target.php similarity index 100% rename from framework/logging/Target.php rename to yii/logging/Target.php diff --git a/framework/logging/WebTarget.php b/yii/logging/WebTarget.php similarity index 100% rename from framework/logging/WebTarget.php rename to yii/logging/WebTarget.php diff --git a/framework/renderers/SmartyViewRenderer.php b/yii/renderers/SmartyViewRenderer.php similarity index 91% rename from framework/renderers/SmartyViewRenderer.php rename to yii/renderers/SmartyViewRenderer.php index cb82438..c6147c0 100644 --- a/framework/renderers/SmartyViewRenderer.php +++ b/yii/renderers/SmartyViewRenderer.php @@ -24,11 +24,6 @@ use yii\helpers\Html; class SmartyViewRenderer extends ViewRenderer { /** - * @var string the directory or path alias pointing to where Smarty code is located. - */ - public $smartyPath = '@yii/vendor/smarty/smarty/distribution/libs'; - - /** * @var string the directory or path alias pointing to where Smarty cache will be stored. */ public $cachePath = '@app/runtime/Smarty/cache'; @@ -45,7 +40,6 @@ class SmartyViewRenderer extends ViewRenderer public function init() { - require_once(Yii::getAlias($this->smartyPath) . '/Smarty.class.php'); $this->smarty = new Smarty(); $this->smarty->setCompileDir(Yii::getAlias($this->compilePath)); $this->smarty->setCacheDir(Yii::getAlias($this->cachePath)); diff --git a/framework/renderers/TwigViewRenderer.php b/yii/renderers/TwigViewRenderer.php similarity index 88% rename from framework/renderers/TwigViewRenderer.php rename to yii/renderers/TwigViewRenderer.php index d48dc5b..de561d3 100644 --- a/framework/renderers/TwigViewRenderer.php +++ b/yii/renderers/TwigViewRenderer.php @@ -23,11 +23,6 @@ use yii\helpers\Html; class TwigViewRenderer extends ViewRenderer { /** - * @var string the directory or path alias pointing to where Twig code is located. - */ - public $twigPath = '@yii/vendor/twig/twig/lib/Twig'; - - /** * @var string the directory or path alias pointing to where Twig cache will be stored. */ public $cachePath = '@app/runtime/Twig/cache'; @@ -45,10 +40,6 @@ class TwigViewRenderer extends ViewRenderer public function init() { - if (!isset(Yii::$aliases['@Twig'])) { - Yii::setAlias('@Twig', $this->twigPath); - } - $loader = new \Twig_Loader_String(); $this->twig = new \Twig_Environment($loader, array_merge(array( diff --git a/framework/test/TestCase.php b/yii/test/TestCase.php similarity index 100% rename from framework/test/TestCase.php rename to yii/test/TestCase.php diff --git a/framework/test/WebTestCase.php b/yii/test/WebTestCase.php similarity index 100% rename from framework/test/WebTestCase.php rename to yii/test/WebTestCase.php diff --git a/framework/validators/BooleanValidator.php b/yii/validators/BooleanValidator.php similarity index 100% rename from framework/validators/BooleanValidator.php rename to yii/validators/BooleanValidator.php diff --git a/framework/validators/CaptchaValidator.php b/yii/validators/CaptchaValidator.php similarity index 97% rename from framework/validators/CaptchaValidator.php rename to yii/validators/CaptchaValidator.php index 4eba9df..2e58cf2 100644 --- a/framework/validators/CaptchaValidator.php +++ b/yii/validators/CaptchaValidator.php @@ -21,6 +21,7 @@ use yii\helpers\Html; */ class CaptchaValidator extends Validator { + public $skipOnEmpty = false; /** * @var boolean whether the comparison is case sensitive. Defaults to false. */ @@ -70,7 +71,7 @@ class CaptchaValidator extends Validator /** * Returns the CAPTCHA action object. * @throws InvalidConfigException - * @return CaptchaAction the action object + * @return \yii\web\CaptchaAction the action object */ public function getCaptchaAction() { diff --git a/framework/validators/CompareValidator.php b/yii/validators/CompareValidator.php similarity index 100% rename from framework/validators/CompareValidator.php rename to yii/validators/CompareValidator.php diff --git a/framework/validators/DateValidator.php b/yii/validators/DateValidator.php similarity index 100% rename from framework/validators/DateValidator.php rename to yii/validators/DateValidator.php diff --git a/framework/validators/DefaultValueValidator.php b/yii/validators/DefaultValueValidator.php similarity index 100% rename from framework/validators/DefaultValueValidator.php rename to yii/validators/DefaultValueValidator.php diff --git a/framework/validators/EmailValidator.php b/yii/validators/EmailValidator.php similarity index 100% rename from framework/validators/EmailValidator.php rename to yii/validators/EmailValidator.php diff --git a/framework/validators/ExistValidator.php b/yii/validators/ExistValidator.php similarity index 100% rename from framework/validators/ExistValidator.php rename to yii/validators/ExistValidator.php diff --git a/framework/validators/FileValidator.php b/yii/validators/FileValidator.php similarity index 100% rename from framework/validators/FileValidator.php rename to yii/validators/FileValidator.php diff --git a/framework/validators/FilterValidator.php b/yii/validators/FilterValidator.php similarity index 100% rename from framework/validators/FilterValidator.php rename to yii/validators/FilterValidator.php diff --git a/framework/validators/InlineValidator.php b/yii/validators/InlineValidator.php similarity index 100% rename from framework/validators/InlineValidator.php rename to yii/validators/InlineValidator.php diff --git a/framework/validators/NumberValidator.php b/yii/validators/NumberValidator.php similarity index 100% rename from framework/validators/NumberValidator.php rename to yii/validators/NumberValidator.php diff --git a/framework/validators/RangeValidator.php b/yii/validators/RangeValidator.php similarity index 100% rename from framework/validators/RangeValidator.php rename to yii/validators/RangeValidator.php diff --git a/framework/validators/RegularExpressionValidator.php b/yii/validators/RegularExpressionValidator.php similarity index 100% rename from framework/validators/RegularExpressionValidator.php rename to yii/validators/RegularExpressionValidator.php diff --git a/framework/validators/RequiredValidator.php b/yii/validators/RequiredValidator.php similarity index 100% rename from framework/validators/RequiredValidator.php rename to yii/validators/RequiredValidator.php diff --git a/framework/validators/StringValidator.php b/yii/validators/StringValidator.php similarity index 100% rename from framework/validators/StringValidator.php rename to yii/validators/StringValidator.php diff --git a/framework/validators/UniqueValidator.php b/yii/validators/UniqueValidator.php similarity index 100% rename from framework/validators/UniqueValidator.php rename to yii/validators/UniqueValidator.php diff --git a/framework/validators/UrlValidator.php b/yii/validators/UrlValidator.php similarity index 100% rename from framework/validators/UrlValidator.php rename to yii/validators/UrlValidator.php diff --git a/framework/validators/Validator.php b/yii/validators/Validator.php similarity index 100% rename from framework/validators/Validator.php rename to yii/validators/Validator.php diff --git a/framework/views/error.php b/yii/views/error.php similarity index 100% rename from framework/views/error.php rename to yii/views/error.php diff --git a/framework/views/exception.php b/yii/views/exception.php similarity index 100% rename from framework/views/exception.php rename to yii/views/exception.php diff --git a/framework/views/migration.php b/yii/views/migration.php similarity index 100% rename from framework/views/migration.php rename to yii/views/migration.php diff --git a/framework/web/AccessControl.php b/yii/web/AccessControl.php similarity index 100% rename from framework/web/AccessControl.php rename to yii/web/AccessControl.php diff --git a/framework/web/AccessRule.php b/yii/web/AccessRule.php similarity index 100% rename from framework/web/AccessRule.php rename to yii/web/AccessRule.php diff --git a/framework/web/Application.php b/yii/web/Application.php similarity index 100% rename from framework/web/Application.php rename to yii/web/Application.php diff --git a/framework/web/AssetBundle.php b/yii/web/AssetBundle.php similarity index 100% rename from framework/web/AssetBundle.php rename to yii/web/AssetBundle.php diff --git a/framework/web/AssetConverter.php b/yii/web/AssetConverter.php similarity index 100% rename from framework/web/AssetConverter.php rename to yii/web/AssetConverter.php diff --git a/framework/web/AssetManager.php b/yii/web/AssetManager.php similarity index 100% rename from framework/web/AssetManager.php rename to yii/web/AssetManager.php diff --git a/framework/web/CacheSession.php b/yii/web/CacheSession.php similarity index 100% rename from framework/web/CacheSession.php rename to yii/web/CacheSession.php diff --git a/yii/web/CaptchaAction.php b/yii/web/CaptchaAction.php new file mode 100644 index 0000000..e3d6eaa --- /dev/null +++ b/yii/web/CaptchaAction.php @@ -0,0 +1,338 @@ + + * @since 2.0 + */ +class CaptchaAction extends Action +{ + /** + * The name of the GET parameter indicating whether the CAPTCHA image should be regenerated. + */ + const REFRESH_GET_VAR = 'refresh'; + /** + * @var integer how many times should the same CAPTCHA be displayed. Defaults to 3. + * A value less than or equal to 0 means the test is unlimited (available since version 1.1.2). + */ + public $testLimit = 3; + /** + * @var integer the width of the generated CAPTCHA image. Defaults to 120. + */ + public $width = 120; + /** + * @var integer the height of the generated CAPTCHA image. Defaults to 50. + */ + public $height = 50; + /** + * @var integer padding around the text. Defaults to 2. + */ + public $padding = 2; + /** + * @var integer the background color. For example, 0x55FF00. + * Defaults to 0xFFFFFF, meaning white color. + */ + public $backColor = 0xFFFFFF; + /** + * @var integer the font color. For example, 0x55FF00. Defaults to 0x2040A0 (blue color). + */ + public $foreColor = 0x2040A0; + /** + * @var boolean whether to use transparent background. Defaults to false. + */ + public $transparent = false; + /** + * @var integer the minimum length for randomly generated word. Defaults to 6. + */ + public $minLength = 6; + /** + * @var integer the maximum length for randomly generated word. Defaults to 7. + */ + public $maxLength = 7; + /** + * @var integer the offset between characters. Defaults to -2. You can adjust this property + * in order to decrease or increase the readability of the captcha. + **/ + public $offset = -2; + /** + * @var string the TrueType font file. This can be either a file path or path alias. + */ + public $fontFile = '@yii/web/SpicyRice.ttf'; + /** + * @var string the fixed verification code. When this is property is set, + * [[getVerifyCode()]] will always return the value of this property. + * This is mainly used in automated tests where we want to be able to reproduce + * the same verification code each time we run the tests. + * If not set, it means the verification code will be randomly generated. + */ + public $fixedVerifyCode; + + + /** + * Initializes the action. + * @throws InvalidConfigException if the font file does not exist. + */ + public function init() + { + $this->fontFile = Yii::getAlias($this->fontFile); + if (!is_file($this->fontFile)) { + throw new InvalidConfigException("The font file does not exist: {$this->fontFile}"); + } + } + + /** + * Runs the action. + */ + public function run() + { + if (isset($_GET[self::REFRESH_GET_VAR])) { + // AJAX request for regenerating code + $code = $this->getVerifyCode(true); + echo json_encode(array( + 'hash1' => $this->generateValidationHash($code), + 'hash2' => $this->generateValidationHash(strtolower($code)), + // we add a random 'v' parameter so that FireFox can refresh the image + // when src attribute of image tag is changed + 'url' => $this->controller->createUrl($this->id, array('v' => uniqid())), + )); + } else { + $this->renderImage($this->getVerifyCode()); + } + Yii::$app->end(); + } + + /** + * Generates a hash code that can be used for client side validation. + * @param string $code the CAPTCHA code + * @return string a hash code generated from the CAPTCHA code + */ + public function generateValidationHash($code) + { + for ($h = 0, $i = strlen($code) - 1; $i >= 0; --$i) { + $h += ord($code[$i]); + } + return $h; + } + + /** + * Gets the verification code. + * @param boolean $regenerate whether the verification code should be regenerated. + * @return string the verification code. + */ + public function getVerifyCode($regenerate = false) + { + if ($this->fixedVerifyCode !== null) { + return $this->fixedVerifyCode; + } + + $session = Yii::$app->session; + $session->open(); + $name = $this->getSessionKey(); + if ($session[$name] === null || $regenerate) { + $session[$name] = $this->generateVerifyCode(); + $session[$name . 'count'] = 1; + } + return $session[$name]; + } + + /** + * Validates the input to see if it matches the generated code. + * @param string $input user input + * @param boolean $caseSensitive whether the comparison should be case-sensitive + * @return boolean whether the input is valid + */ + public function validate($input, $caseSensitive) + { + $code = $this->getVerifyCode(); + $valid = $caseSensitive ? ($input === $code) : strcasecmp($input, $code) === 0; + $session = Yii::$app->session; + $session->open(); + $name = $this->getSessionKey() . 'count'; + $session[$name] = $session[$name] + 1; + if ($session[$name] > $this->testLimit && $this->testLimit > 0) { + $this->getVerifyCode(true); + } + return $valid; + } + + /** + * Generates a new verification code. + * @return string the generated verification code + */ + protected function generateVerifyCode() + { + if ($this->minLength < 3) { + $this->minLength = 3; + } + if ($this->maxLength > 20) { + $this->maxLength = 20; + } + if ($this->minLength > $this->maxLength) { + $this->maxLength = $this->minLength; + } + $length = mt_rand($this->minLength, $this->maxLength); + + $letters = 'bcdfghjklmnpqrstvwxyz'; + $vowels = 'aeiou'; + $code = ''; + for ($i = 0; $i < $length; ++$i) { + if ($i % 2 && mt_rand(0, 10) > 2 || !($i % 2) && mt_rand(0, 10) > 9) { + $code .= $vowels[mt_rand(0, 4)]; + } else { + $code .= $letters[mt_rand(0, 20)]; + } + } + + return $code; + } + + /** + * Returns the session variable name used to store verification code. + * @return string the session variable name + */ + protected function getSessionKey() + { + return '__captcha/' . $this->getUniqueId(); + } + + /** + * Renders the CAPTCHA image. + * @param string $code the verification code + */ + protected function renderImage($code) + { + if (Captcha::checkRequirements() === 'gd') { + $this->renderImageByGD($code); + } else { + $this->renderImageByImagick($code); + } + } + + /** + * Renders the CAPTCHA image based on the code using GD library. + * @param string $code the verification code + */ + protected function renderImageByGD($code) + { + $image = imagecreatetruecolor($this->width, $this->height); + + $backColor = imagecolorallocate($image, + (int)($this->backColor % 0x1000000 / 0x10000), + (int)($this->backColor % 0x10000 / 0x100), + $this->backColor % 0x100); + imagefilledrectangle($image, 0, 0, $this->width, $this->height, $backColor); + imagecolordeallocate($image, $backColor); + + if ($this->transparent) { + imagecolortransparent($image, $backColor); + } + + $foreColor = imagecolorallocate($image, + (int)($this->foreColor % 0x1000000 / 0x10000), + (int)($this->foreColor % 0x10000 / 0x100), + $this->foreColor % 0x100); + + if ($this->fontFile === null) { + $this->fontFile = dirname(__FILE__) . '/SpicyRice.ttf'; + } + + $length = strlen($code); + $box = imagettfbbox(30, 0, $this->fontFile, $code); + $w = $box[4] - $box[0] + $this->offset * ($length - 1); + $h = $box[1] - $box[5]; + $scale = min(($this->width - $this->padding * 2) / $w, ($this->height - $this->padding * 2) / $h); + $x = 10; + $y = round($this->height * 27 / 40); + for ($i = 0; $i < $length; ++$i) { + $fontSize = (int)(rand(26, 32) * $scale * 0.8); + $angle = rand(-10, 10); + $letter = $code[$i]; + $box = imagettftext($image, $fontSize, $angle, $x, $y, $foreColor, $this->fontFile, $letter); + $x = $box[2] + $this->offset; + } + + imagecolordeallocate($image, $foreColor); + + header('Pragma: public'); + header('Expires: 0'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Content-Transfer-Encoding: binary'); + header("Content-type: image/png"); + imagepng($image); + imagedestroy($image); + } + + /** + * Renders the CAPTCHA image based on the code using ImageMagick library. + * @param string $code the verification code + */ + protected function renderImageByImagick($code) + { + $backColor = $this->transparent ? new \ImagickPixel('transparent') : new \ImagickPixel('#' . dechex($this->backColor)); + $foreColor = new \ImagickPixel('#' . dechex($this->foreColor)); + + $image = new \Imagick(); + $image->newImage($this->width, $this->height, $backColor); + + if ($this->fontFile === null) { + $this->fontFile = dirname(__FILE__) . '/SpicyRice.ttf'; + } + + $draw = new \ImagickDraw(); + $draw->setFont($this->fontFile); + $draw->setFontSize(30); + $fontMetrics = $image->queryFontMetrics($draw, $code); + + $length = strlen($code); + $w = (int)($fontMetrics['textWidth']) - 8 + $this->offset * ($length - 1); + $h = (int)($fontMetrics['textHeight']) - 8; + $scale = min(($this->width - $this->padding * 2) / $w, ($this->height - $this->padding * 2) / $h); + $x = 10; + $y = round($this->height * 27 / 40); + for ($i = 0; $i < $length; ++$i) { + $draw = new \ImagickDraw(); + $draw->setFont($this->fontFile); + $draw->setFontSize((int)(rand(26, 32) * $scale * 0.8)); + $draw->setFillColor($foreColor); + $image->annotateImage($draw, $x, $y, rand(-10, 10), $code[$i]); + $fontMetrics = $image->queryFontMetrics($draw, $code[$i]); + $x += (int)($fontMetrics['textWidth']) + $this->offset; + } + + header('Pragma: public'); + header('Expires: 0'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Content-Transfer-Encoding: binary'); + header("Content-type: image/png"); + $image->setImageFormat('png'); + echo $image; + } +} diff --git a/framework/web/Controller.php b/yii/web/Controller.php similarity index 100% rename from framework/web/Controller.php rename to yii/web/Controller.php diff --git a/framework/web/Cookie.php b/yii/web/Cookie.php similarity index 100% rename from framework/web/Cookie.php rename to yii/web/Cookie.php diff --git a/framework/web/CookieCollection.php b/yii/web/CookieCollection.php similarity index 100% rename from framework/web/CookieCollection.php rename to yii/web/CookieCollection.php diff --git a/framework/web/DbSession.php b/yii/web/DbSession.php similarity index 100% rename from framework/web/DbSession.php rename to yii/web/DbSession.php diff --git a/framework/web/HttpCache.php b/yii/web/HttpCache.php similarity index 100% rename from framework/web/HttpCache.php rename to yii/web/HttpCache.php diff --git a/framework/web/IAssetConverter.php b/yii/web/IAssetConverter.php similarity index 100% rename from framework/web/IAssetConverter.php rename to yii/web/IAssetConverter.php diff --git a/framework/web/Identity.php b/yii/web/Identity.php similarity index 100% rename from framework/web/Identity.php rename to yii/web/Identity.php diff --git a/framework/web/JsExpression.php b/yii/web/JsExpression.php similarity index 100% rename from framework/web/JsExpression.php rename to yii/web/JsExpression.php diff --git a/framework/web/PageCache.php b/yii/web/PageCache.php similarity index 100% rename from framework/web/PageCache.php rename to yii/web/PageCache.php diff --git a/framework/web/Pagination.php b/yii/web/Pagination.php similarity index 100% rename from framework/web/Pagination.php rename to yii/web/Pagination.php diff --git a/framework/web/Request.php b/yii/web/Request.php similarity index 99% rename from framework/web/Request.php rename to yii/web/Request.php index 5e2f064..d3f419b 100644 --- a/framework/web/Request.php +++ b/yii/web/Request.php @@ -69,8 +69,8 @@ class Request extends \yii\base\Request $result = Yii::$app->getUrlManager()->parseRequest($this); if ($result !== false) { list ($route, $params) = $result; - $params = array_merge($_GET, $params); - return array($route, $params); + $_GET = array_merge($_GET, $params); + return array($route, $_GET); } else { throw new HttpException(404, Yii::t('yii|Page not found.')); } diff --git a/framework/web/Response.php b/yii/web/Response.php similarity index 100% rename from framework/web/Response.php rename to yii/web/Response.php diff --git a/framework/web/Session.php b/yii/web/Session.php similarity index 100% rename from framework/web/Session.php rename to yii/web/Session.php diff --git a/framework/web/SessionIterator.php b/yii/web/SessionIterator.php similarity index 100% rename from framework/web/SessionIterator.php rename to yii/web/SessionIterator.php diff --git a/framework/web/Sort.php b/yii/web/Sort.php similarity index 100% rename from framework/web/Sort.php rename to yii/web/Sort.php diff --git a/yii/web/SpicyRice.md b/yii/web/SpicyRice.md new file mode 100644 index 0000000..d99f3dc --- /dev/null +++ b/yii/web/SpicyRice.md @@ -0,0 +1,11 @@ +## Spicy Rice font + +* **Author:** Brian J. Bonislawsky, Astigmatic (AOETI, Astigmatic One Eye Typographic Institute) +* **License:** SIL Open Font License (OFL), version 1.1, [notes and FAQ](http://scripts.sil.org/OFL) + +## Links + +* [Astigmatic](http://www.astigmatic.com/) +* [Google WebFonts](http://www.google.com/webfonts/specimen/Spicy+Rice) +* [fontsquirrel.com](http://www.fontsquirrel.com/fonts/spicy-rice) +* [fontspace.com](http://www.fontspace.com/astigmatic-one-eye-typographic-institute/spicy-rice) diff --git a/yii/web/SpicyRice.ttf b/yii/web/SpicyRice.ttf new file mode 100644 index 0000000..638436c Binary files /dev/null and b/yii/web/SpicyRice.ttf differ diff --git a/framework/web/UploadedFile.php b/yii/web/UploadedFile.php similarity index 100% rename from framework/web/UploadedFile.php rename to yii/web/UploadedFile.php diff --git a/framework/web/UrlManager.php b/yii/web/UrlManager.php similarity index 100% rename from framework/web/UrlManager.php rename to yii/web/UrlManager.php diff --git a/framework/web/UrlRule.php b/yii/web/UrlRule.php similarity index 98% rename from framework/web/UrlRule.php rename to yii/web/UrlRule.php index 53bd747..96cb994 100644 --- a/framework/web/UrlRule.php +++ b/yii/web/UrlRule.php @@ -125,7 +125,7 @@ class UrlRule extends Object if (isset($this->defaults[$name])) { $length = strlen($match[0][0]); $offset = $match[0][1]; - if ($this->pattern[$offset - 1] === '/' && $this->pattern[$offset + $length] === '/') { + if ($offset > 1 && $this->pattern[$offset - 1] === '/' && $this->pattern[$offset + $length] === '/') { $tr["/<$name>"] = "(/(?P<$name>$pattern))?"; } else { $tr["<$name>"] = "(?P<$name>$pattern)?"; diff --git a/framework/web/User.php b/yii/web/User.php similarity index 100% rename from framework/web/User.php rename to yii/web/User.php diff --git a/framework/web/UserEvent.php b/yii/web/UserEvent.php similarity index 100% rename from framework/web/UserEvent.php rename to yii/web/UserEvent.php diff --git a/framework/widgets/ActiveField.php b/yii/widgets/ActiveField.php similarity index 99% rename from framework/widgets/ActiveField.php rename to yii/widgets/ActiveField.php index aaa9470..9f3f201 100644 --- a/framework/widgets/ActiveField.php +++ b/yii/widgets/ActiveField.php @@ -152,7 +152,7 @@ class ActiveField extends Component $options['enableAjaxValidation'] = 1; } - if ($enableClientValidation || $enableAjaxValidation) { + if ($enableClientValidation && !empty($options['validate']) || $enableAjaxValidation) { $inputID = Html::getInputId($this->model, $this->attribute); $options['name'] = $inputID; $names = array( diff --git a/framework/widgets/ActiveForm.php b/yii/widgets/ActiveForm.php similarity index 100% rename from framework/widgets/ActiveForm.php rename to yii/widgets/ActiveForm.php diff --git a/framework/widgets/Block.php b/yii/widgets/Block.php similarity index 100% rename from framework/widgets/Block.php rename to yii/widgets/Block.php diff --git a/framework/widgets/Breadcrumbs.php b/yii/widgets/Breadcrumbs.php similarity index 100% rename from framework/widgets/Breadcrumbs.php rename to yii/widgets/Breadcrumbs.php diff --git a/yii/widgets/Captcha.php b/yii/widgets/Captcha.php new file mode 100644 index 0000000..918e30c --- /dev/null +++ b/yii/widgets/Captcha.php @@ -0,0 +1,102 @@ + + * @since 2.0 + */ +class Captcha extends Widget +{ + /** + * @var string the route of the action that generates the CAPTCHA images. + * The action represented by this route must be an action of [[CaptchaAction]]. + */ + public $captchaAction = 'site/captcha'; + /** + * @var array HTML attributes to be applied to the rendered image element. + */ + public $options = array(); + + + /** + * Renders the widget. + */ + public function run() + { + $this->checkRequirements(); + + if (!isset($this->options['id'])) { + $this->options['id'] = $this->getId(); + } + $id = $this->options['id']; + $options = Json::encode($this->getClientOptions()); + $this->view->registerAssetBundle('yii/captcha'); + $this->view->registerJs("jQuery('#$id').yiiCaptcha($options);"); + $url = Yii::$app->getUrlManager()->createUrl($this->captchaAction, array('v' => uniqid())); + echo Html::img($url, $this->options); + } + + /** + * Returns the options for the captcha JS widget. + * @return array the options + */ + protected function getClientOptions() + { + $options = array( + 'refreshUrl' => Html::url(array($this->captchaAction, CaptchaAction::REFRESH_GET_VAR => 1)), + 'hashKey' => "yiiCaptcha/{$this->captchaAction}", + ); + return $options; + } + + /** + * Checks if there is graphic extension available to generate CAPTCHA images. + * This method will check the existence of ImageMagick and GD extensions. + * @return string the name of the graphic extension, either "imagick" or "gd". + * @throws InvalidConfigException if neither ImageMagick nor GD is installed. + */ + public static function checkRequirements() + { + if (extension_loaded('imagick')) { + $imagick = new \Imagick(); + $imagickFormats = $imagick->queryFormats('PNG'); + if (in_array('PNG', $imagickFormats)) { + return 'imagick'; + } + } + if (extension_loaded('gd')) { + $gdInfo = gd_info(); + if (!empty($gdInfo['FreeType Support'])) { + return 'gd'; + } + } + throw new InvalidConfigException('GD with FreeType or ImageMagick PHP extensions are required.'); + } +} diff --git a/framework/widgets/ContentDecorator.php b/yii/widgets/ContentDecorator.php similarity index 100% rename from framework/widgets/ContentDecorator.php rename to yii/widgets/ContentDecorator.php diff --git a/framework/widgets/FragmentCache.php b/yii/widgets/FragmentCache.php similarity index 100% rename from framework/widgets/FragmentCache.php rename to yii/widgets/FragmentCache.php diff --git a/framework/widgets/Menu.php b/yii/widgets/Menu.php similarity index 100% rename from framework/widgets/Menu.php rename to yii/widgets/Menu.php diff --git a/framework/yiic b/yii/yiic similarity index 100% rename from framework/yiic rename to yii/yiic diff --git a/framework/yiic.bat b/yii/yiic.bat similarity index 100% rename from framework/yiic.bat rename to yii/yiic.bat diff --git a/framework/yiic.php b/yii/yiic.php similarity index 94% rename from framework/yiic.php rename to yii/yiic.php index 3872e2f..7cd0c40 100644 --- a/framework/yiic.php +++ b/yii/yiic.php @@ -12,7 +12,7 @@ defined('YII_DEBUG') or define('YII_DEBUG', true); // fcgi doesn't have STDIN defined by default defined('STDIN') or define('STDIN', fopen('php://stdin', 'r')); -require(__DIR__ . '/yii.php'); +require(__DIR__ . '/Yii.php'); $application = new yii\console\Application(array( 'id' => 'yiic',