├── web ├── files │ └── hello.txt ├── assets │ └── .gitignore ├── robots.txt ├── js │ ├── main-index.js │ └── main.js ├── favicon.ico ├── img │ └── brand.gif ├── .htaccess ├── index.php ├── index-test.php └── css │ ├── main.css │ └── site.css ├── runtime └── .gitignore ├── tests ├── codeception │ ├── unit │ │ ├── fixtures │ │ │ ├── .gitkeep │ │ │ └── data │ │ │ │ └── .gitkeep │ │ ├── templates │ │ │ └── fixtures │ │ │ │ └── .gitkeep │ │ ├── _bootstrap.php │ │ └── models │ │ │ ├── UserTest.php │ │ │ ├── ContactFormTest.php │ │ │ └── LoginFormTest.php │ ├── _output │ │ └── .gitignore │ ├── fixtures │ │ └── .gitignore │ ├── templates │ │ └── .gitignore │ ├── acceptance │ │ ├── _bootstrap.php │ │ ├── AboutCept.php │ │ ├── HomeCept.php │ │ ├── LoginCept.php │ │ └── ContactCept.php │ ├── functional │ │ ├── _bootstrap.php │ │ ├── AboutCept.php │ │ ├── HomeCept.php │ │ ├── LoginCept.php │ │ └── ContactCept.php │ ├── .gitignore │ ├── unit.suite.yml │ ├── config │ │ ├── unit.php │ │ ├── acceptance.php │ │ ├── config.php │ │ └── functional.php │ ├── _pages │ │ ├── AboutPage.php │ │ ├── LoginPage.php │ │ └── ContactPage.php │ ├── functional.suite.yml │ ├── bin │ │ ├── yii.bat │ │ ├── _bootstrap.php │ │ └── yii │ ├── _bootstrap.php │ └── acceptance.suite.yml ├── codeception.yml └── README.md ├── .bowerrc ├── views ├── widget-test │ └── index.php ├── main │ ├── index.php │ ├── search.php │ ├── sendEmail.php │ ├── resetPassword.php │ ├── profile.php │ ├── reg.php │ └── login.php ├── site │ ├── about.php │ ├── error.php │ ├── login.php │ ├── contact.php │ └── index.php └── layouts │ ├── main.php │ └── basic.php ├── components ├── views │ ├── second.php │ └── first.php ├── SecondWidget.php ├── FirstWidget.php ├── MyBehaviors.php └── AlertWidget.php ├── config ├── db.php ├── params.php ├── console.php └── web.php ├── controllers ├── WidgetTestController.php ├── BehaviorsController.php ├── SiteController.php └── MainController.php ├── migrations ├── m150211_193807_drop_post_table.php ├── m150330_153014_drop_user_table.php ├── m150211_165754_create_user_table.php ├── m150211_170614_create_post_table.php ├── m150330_153138_create_user_table.php ├── m150527_004551_drop_user_table.php ├── m150804_021125_add_secret_key_in_user_table.php ├── m150527_004737_create_user_table.php └── m150711_083606_create_profile_table.php ├── mail ├── resetPassword.php ├── activationEmail.php └── layouts │ └── html.php ├── .gitignore ├── yii.bat ├── yii ├── assets └── AppAsset.php ├── commands └── HelloController.php ├── models ├── AccountActivation.php ├── ResetPasswordForm.php ├── SendEmailForm.php ├── ContactForm.php ├── Profile.php ├── LoginForm.php ├── RegForm.php └── User.php ├── LICENSE.md ├── composer.json ├── README.md ├── requirements.php └── composer.lock /web/files/hello.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /runtime/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /tests/codeception/unit/fixtures/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/assets/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /web/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: -------------------------------------------------------------------------------- /tests/codeception/unit/fixtures/data/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/codeception/_output/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /tests/codeception/unit/templates/fixtures/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory" : "vendor/bower" 3 | } 4 | -------------------------------------------------------------------------------- /tests/codeception/fixtures/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /tests/codeception/templates/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /views/widget-test/index.php: -------------------------------------------------------------------------------- 1 | 5 |
8 | = $hello ?> 9 |
10 | -------------------------------------------------------------------------------- /tests/codeception/.gitignore: -------------------------------------------------------------------------------- 1 | # these files are auto generated by codeception build 2 | /unit/UnitTester.php 3 | /functional/FunctionalTester.php 4 | /acceptance/AcceptanceTester.php 5 | -------------------------------------------------------------------------------- /views/main/search.php: -------------------------------------------------------------------------------- 1 | 9 |= $content ?>
-------------------------------------------------------------------------------- /tests/codeception/unit.suite.yml: -------------------------------------------------------------------------------- 1 | # Codeception Test Suite Configuration 2 | 3 | # suite for unit (internal) tests. 4 | # RUN `build` COMMAND AFTER ADDING/REMOVING MODULES. 5 | 6 | class_name: UnitTester 7 | -------------------------------------------------------------------------------- /config/db.php: -------------------------------------------------------------------------------- 1 | 'yii\db\Connection', 5 | 'dsn' => 'mysql:host=localhost;dbname=basic', 6 | 'username' => 'root', 7 | 'password' => '', 8 | 'charset' => 'utf8', 9 | ]; 10 | -------------------------------------------------------------------------------- /web/.htaccess: -------------------------------------------------------------------------------- 1 | RewriteEngine on 2 | 3 | # if a directory or a file exists, use it directly 4 | RewriteCond %{REQUEST_FILENAME} !-f 5 | RewriteCond %{REQUEST_FILENAME} !-d 6 | 7 | # otherwise forward it to index.php 8 | RewriteRule . index.php -------------------------------------------------------------------------------- /tests/codeception/acceptance/AboutCept.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that about works'); 7 | AboutPage::openBy($I); 8 | $I->see('About', 'h1'); 9 | -------------------------------------------------------------------------------- /tests/codeception/functional/AboutCept.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that about works'); 7 | AboutPage::openBy($I); 8 | $I->see('About', 'h1'); 9 | -------------------------------------------------------------------------------- /components/views/first.php: -------------------------------------------------------------------------------- 1 | 10 |12 | = 'Сумма A и B равна '.$c; ?> 13 |
-------------------------------------------------------------------------------- /tests/codeception/config/unit.php: -------------------------------------------------------------------------------- 1 | render( 10 | 'index' 11 | ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/codeception/config/acceptance.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that home page works'); 5 | $I->amOnPage(Yii::$app->homeUrl); 6 | $I->see('My Company'); 7 | $I->seeLink('About'); 8 | $I->click('About'); 9 | $I->see('This is the About page.'); 10 | -------------------------------------------------------------------------------- /tests/codeception/functional/HomeCept.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that home page works'); 5 | $I->amOnPage(Yii::$app->homeUrl); 6 | $I->see('My Company'); 7 | $I->seeLink('About'); 8 | $I->click('About'); 9 | $I->see('This is the About page.'); 10 | -------------------------------------------------------------------------------- /tests/codeception/_pages/AboutPage.php: -------------------------------------------------------------------------------- 1 | run(); 13 | -------------------------------------------------------------------------------- /migrations/m150211_193807_drop_post_table.php: -------------------------------------------------------------------------------- 1 | dropTable('post'); 11 | } 12 | 13 | public function down() 14 | { 15 | echo "m150211_193807_drop_post_table cannot be reverted.\n"; 16 | 17 | return false; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /migrations/m150330_153014_drop_user_table.php: -------------------------------------------------------------------------------- 1 | dropTable('user'); 11 | } 12 | 13 | public function down() 14 | { 15 | echo "m150330_153014_drop_user_table cannot be reverted.\n"; 16 | 17 | return false; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/codeception/unit/models/UserTest.php: -------------------------------------------------------------------------------- 1 | loadFixtures(['user']); 14 | } 15 | 16 | // TODO add test methods here 17 | } 18 | -------------------------------------------------------------------------------- /views/site/about.php: -------------------------------------------------------------------------------- 1 | title = 'About'; 6 | $this->params['breadcrumbs'][] = $this->title; 7 | ?> 8 |12 | This is the About page. You may modify the following file to customize its content: 13 |
14 | 15 |= __FILE__ ?>
16 | 21 | The above error occurred while the Web server was processing your request. 22 |
23 |24 | Please contact us if you think this is a server error. Thank you. 25 |
26 | 27 |Please fill out the following fields to login:
16 | 17 | 'login-form', 19 | 'options' => ['class' => 'form-horizontal'], 20 | 'fieldConfig' => [ 21 | 'template' => "{label}\napp\models\User::$users.
45 |
23 | Note that if you turn on the Yii debugger, you should be able
24 | to view the mail message on the mail panel of the debugger.
25 | mailer->useFileTransport): ?>
26 | Because the application is in development mode, the email is not sent but saved as
27 | a file under = Yii::getAlias(Yii::$app->mailer->fileTransportPath) ?>.
28 | Please configure the useFileTransport property of the mail
29 | application component to be false to enable email sending.
30 |
31 |
36 | If you have business inquiries or other questions, please fill out the following form to contact us. Thank you. 37 |
38 | 39 |You have successfully created your Yii-powered application.
11 | 12 | 13 |Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et 22 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip 23 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 24 | fugiat nulla pariatur.
25 | 26 | 27 |Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et 32 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip 33 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 34 | fugiat nulla pariatur.
35 | 36 | 37 |Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et 42 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip 43 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 44 | fugiat nulla pariatur.
45 | 46 | 47 |The path to yii framework seems to be incorrect.
'; 19 | echo 'You need to install Yii framework via composer or adjust the framework path in file ' . basename(__FILE__) . '.
'; 20 | echo 'Please refer to the README on how to install Yii.
'; 21 | } 22 | 23 | require_once($frameworkPath . '/requirements/YiiRequirementChecker.php'); 24 | $requirementsChecker = new YiiRequirementChecker(); 25 | 26 | $gdMemo = $imagickMemo = 'Either GD PHP extension with FreeType support or ImageMagick PHP extension with PNG support is required for image CAPTCHA.'; 27 | $gdOK = $imagickOK = false; 28 | 29 | if (extension_loaded('imagick')) { 30 | $imagick = new Imagick(); 31 | $imagickFormats = $imagick->queryFormats('PNG'); 32 | if (in_array('PNG', $imagickFormats)) { 33 | $imagickOK = true; 34 | } else { 35 | $imagickMemo = 'Imagick extension should be installed with PNG support in order to be used for image CAPTCHA.'; 36 | } 37 | } 38 | 39 | if (extension_loaded('gd')) { 40 | $gdInfo = gd_info(); 41 | if (!empty($gdInfo['FreeType Support'])) { 42 | $gdOK = true; 43 | } else { 44 | $gdMemo = 'GD extension should be installed with FreeType support in order to be used for image CAPTCHA.'; 45 | } 46 | } 47 | 48 | /** 49 | * Adjust requirements according to your application specifics. 50 | */ 51 | $requirements = array( 52 | // Database : 53 | array( 54 | 'name' => 'PDO extension', 55 | 'mandatory' => true, 56 | 'condition' => extension_loaded('pdo'), 57 | 'by' => 'All DB-related classes', 58 | ), 59 | array( 60 | 'name' => 'PDO SQLite extension', 61 | 'mandatory' => false, 62 | 'condition' => extension_loaded('pdo_sqlite'), 63 | 'by' => 'All DB-related classes', 64 | 'memo' => 'Required for SQLite database.', 65 | ), 66 | array( 67 | 'name' => 'PDO MySQL extension', 68 | 'mandatory' => false, 69 | 'condition' => extension_loaded('pdo_mysql'), 70 | 'by' => 'All DB-related classes', 71 | 'memo' => 'Required for MySQL database.', 72 | ), 73 | array( 74 | 'name' => 'PDO PostgreSQL extension', 75 | 'mandatory' => false, 76 | 'condition' => extension_loaded('pdo_pgsql'), 77 | 'by' => 'All DB-related classes', 78 | 'memo' => 'Required for PostgreSQL database.', 79 | ), 80 | // Cache : 81 | array( 82 | 'name' => 'Memcache extension', 83 | 'mandatory' => false, 84 | 'condition' => extension_loaded('memcache') || extension_loaded('memcached'), 85 | 'by' => 'MemCache', 86 | 'memo' => extension_loaded('memcached') ? 'To use memcached set MemCache::useMemcached totrue.' : ''
87 | ),
88 | array(
89 | 'name' => 'APC extension',
90 | 'mandatory' => false,
91 | 'condition' => extension_loaded('apc'),
92 | 'by' => 'ApcCache',
93 | ),
94 | // CAPTCHA:
95 | array(
96 | 'name' => 'GD PHP extension with FreeType support',
97 | 'mandatory' => false,
98 | 'condition' => $gdOK,
99 | 'by' => 'Captcha',
100 | 'memo' => $gdMemo,
101 | ),
102 | array(
103 | 'name' => 'ImageMagick PHP extension with PNG support',
104 | 'mandatory' => false,
105 | 'condition' => $imagickOK,
106 | 'by' => 'Captcha',
107 | 'memo' => $imagickMemo,
108 | ),
109 | // PHP ini :
110 | 'phpExposePhp' => array(
111 | 'name' => 'Expose PHP',
112 | 'mandatory' => false,
113 | 'condition' => $requirementsChecker->checkPhpIniOff("expose_php"),
114 | 'by' => 'Security reasons',
115 | 'memo' => '"expose_php" should be disabled at php.ini',
116 | ),
117 | 'phpAllowUrlInclude' => array(
118 | 'name' => 'PHP allow url include',
119 | 'mandatory' => false,
120 | 'condition' => $requirementsChecker->checkPhpIniOff("allow_url_include"),
121 | 'by' => 'Security reasons',
122 | 'memo' => '"allow_url_include" should be disabled at php.ini',
123 | ),
124 | 'phpSmtp' => array(
125 | 'name' => 'PHP mail SMTP',
126 | 'mandatory' => false,
127 | 'condition' => strlen(ini_get('SMTP'))>0,
128 | 'by' => 'Email sending',
129 | 'memo' => 'PHP mail SMTP server required',
130 | ),
131 | );
132 | $requirementsChecker->checkYii()->check($requirements)->render();
133 |
--------------------------------------------------------------------------------
/models/User.php:
--------------------------------------------------------------------------------
1 | 'trim'],
46 | [['username', 'email', 'status'], 'required'],
47 | ['email', 'email'],
48 | ['username', 'string', 'min' => 2, 'max' => 255],
49 | ['password', 'required', 'on' => 'create'],
50 | ['username', 'unique', 'message' => 'Это имя занято.'],
51 | ['email', 'unique', 'message' => 'Эта почта уже зарегистрирована.'],
52 | ['secret_key', 'unique']
53 | ];
54 | }
55 |
56 | /**
57 | * @inheritdoc
58 | */
59 | public function attributeLabels()
60 | {
61 | return [
62 | 'id' => 'ID',
63 | 'username' => 'Ник',
64 | 'email' => 'Email',
65 | 'password' => 'Password Hash',
66 | 'status' => 'Статус',
67 | 'auth_key' => 'Auth Key',
68 | 'created_at' => 'Дата создания',
69 | 'updated_at' => 'Дата изменения',
70 | ];
71 | }
72 |
73 | /* Связи */
74 | public function getProfile()
75 | {
76 | return $this->hasOne(Profile::className(), ['user_id' => 'id']);
77 | }
78 |
79 | /* Поведения */
80 | public function behaviors()
81 | {
82 | return [
83 | TimestampBehavior::className()
84 | ];
85 | }
86 |
87 | /* Поиск */
88 |
89 | /** Находит пользователя по имени и возвращает объект найденного пользователя.
90 | * Вызываеться из модели LoginForm.
91 | */
92 | public static function findByUsername($username)
93 | {
94 | return static::findOne([
95 | 'username' => $username
96 | ]);
97 | }
98 |
99 | /* Находит пользователя по емайл */
100 | public static function findByEmail($email)
101 | {
102 | return static::findOne([
103 | 'email' => $email
104 | ]);
105 | }
106 |
107 | public static function findBySecretKey($key)
108 | {
109 | if (!static::isSecretKeyExpire($key))
110 | {
111 | return null;
112 | }
113 | return static::findOne([
114 | 'secret_key' => $key,
115 | ]);
116 | }
117 |
118 | /* Хелперы */
119 | public function generateSecretKey()
120 | {
121 | $this->secret_key = Yii::$app->security->generateRandomString().'_'.time();
122 | }
123 |
124 | public function removeSecretKey()
125 | {
126 | $this->secret_key = null;
127 | }
128 |
129 | public static function isSecretKeyExpire($key)
130 | {
131 | if (empty($key))
132 | {
133 | return false;
134 | }
135 | $expire = Yii::$app->params['secretKeyExpire'];
136 | $parts = explode('_', $key);
137 | $timestamp = (int) end($parts);
138 |
139 | return $timestamp + $expire >= time();
140 | }
141 |
142 | /**
143 | * Генерирует хеш из введенного пароля и присваивает (при записи) полученное значение полю password_hash таблицы user для
144 | * нового пользователя.
145 | * Вызываеться из модели RegForm.
146 | */
147 | public function setPassword($password)
148 | {
149 | $this->password_hash = Yii::$app->security->generatePasswordHash($password);
150 | }
151 |
152 | /**
153 | * Генерирует случайную строку из 32 шестнадцатеричных символов и присваивает (при записи) полученное значение полю auth_key
154 | * таблицы user для нового пользователя.
155 | * Вызываеться из модели RegForm.
156 | */
157 | public function generateAuthKey(){
158 | $this->auth_key = Yii::$app->security->generateRandomString();
159 | }
160 |
161 | /**
162 | * Сравнивает полученный пароль с паролем в поле password_hash, для текущего пользователя, в таблице user.
163 | * Вызываеться из модели LoginForm.
164 | */
165 | public function validatePassword($password)
166 | {
167 | return Yii::$app->security->validatePassword($password, $this->password_hash);
168 | }
169 |
170 | /* Аутентификация пользователей */
171 | public static function findIdentity($id)
172 | {
173 | return static::findOne([
174 | 'id' => $id,
175 | 'status' => self::STATUS_ACTIVE
176 | ]);
177 | }
178 |
179 | public static function findIdentityByAccessToken($token, $type = null)
180 | {
181 | return static::findOne(['access_token' => $token]);
182 | }
183 |
184 | public function getId()
185 | {
186 | return $this->id;
187 | }
188 |
189 | public function getAuthKey()
190 | {
191 | return $this->auth_key;
192 | }
193 |
194 | public function validateAuthKey($authKey)
195 | {
196 | return $this->auth_key === $authKey;
197 | }
198 | }
199 |
--------------------------------------------------------------------------------
/views/layouts/basic.php:
--------------------------------------------------------------------------------
1 | beginPage();
20 | ?>
21 |
22 |
23 |
24 | = Html::csrfMetaTags() ?>
25 |
26 | registerMetaTag(['name' => 'viewport', 'content' => 'width=device-width, initial-scale=1']); ?>
27 |
',
46 | 'brandUrl' => [
47 | '/main/index'
48 | ],
49 | 'brandOptions' => [
50 | 'class' => 'navbar-brand'
51 | ]
52 | ]
53 | );
54 | if (!Yii::$app->user->isGuest):
55 | ?>
56 |
70 | 'Из коробки ',
75 | 'items' => [
76 | '