20 changed files with 276 additions and 225 deletions
			
			
		| @ -0,0 +1,59 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* @var $this yii\web\View */ | ||||
| /* @var $model \core\forms\user\ProfileEditForm */ | ||||
| /* @var $user \core\entities\user\User */ | ||||
| 
 | ||||
| use yii\bootstrap\ActiveForm; | ||||
| use yii\helpers\Html; | ||||
| 
 | ||||
| $this->title = Yii::t('user', 'Profile: {username}', ['username' => $user->username]); | ||||
| $this->params['breadcrumbs'][] = ['label' => $user->username, 'url' => ['view', 'id' => $user->id]]; | ||||
| $this->params['breadcrumbs'][] = Yii::t('user', 'Profile'); | ||||
| ?> | ||||
| <div class="user-profile"> | ||||
| 
 | ||||
| 	<?php $form = ActiveForm::begin(); ?> | ||||
| 
 | ||||
| 	<div class="row"> | ||||
| 		<div class="col-md-3"> | ||||
| 			<div class="box box-default"> | ||||
| 				<div class="box-body"> | ||||
| 					<div style="text-align: center"> | ||||
| 						<img style="width: 300px" src="<?= Yii::$app->avatar->show(Yii::$app->user->identity->user->username, null, null, Yii::$app->user->identity->user->user_pic) ?>?<?= rand(10, 5000) ?>" class="img-circle" alt="<?= Yii::$app->user->identity->user->username ?>"/>
 | ||||
| 					</div> | ||||
| 					<!-- < ?= $form->field($model, 'user_pic')->fileInput() ?> --> | ||||
| 					<?= $form->field($model, 'user_pic')->widget(\kartik\widgets\FileInput::class, [ | ||||
| 						'options' => [ | ||||
| 							'accept' => 'image/*' | ||||
| 						], | ||||
| 						'pluginOptions' => [ | ||||
| 							'showPreview' => false, | ||||
| 							'showCaption' => true, | ||||
| 							'showRemove' => true, | ||||
| 							'showUpload' => false | ||||
| 						], | ||||
| 					]); ?> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 		<div class="col-md-6"> | ||||
| 			<div class="box box-default"> | ||||
| 				<div class="box-body"> | ||||
| 					<?= $form->field($model, 'username')->textInput(['maxLength' => true]) ?> | ||||
| 					<?= $form->field($model, 'email')->textInput(['maxLength' => true]) ?> | ||||
| 					<?= $form->field($model, 'password')->passwordInput(['maxLength' => true]) ?> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</div> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     <div class="form-group"> | ||||
|         <?= Html::submitButton(Yii::t('buttons', 'Save'), ['class' => 'btn btn-primary']) ?> | ||||
|     </div> | ||||
| 
 | ||||
|     <?php ActiveForm::end(); ?> | ||||
| 
 | ||||
| </div> | ||||
| @ -1,171 +0,0 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Created by Error202 | ||||
|  * Date: 18.08.2017 | ||||
|  */ | ||||
| 
 | ||||
| namespace core\components\avatar_generator; | ||||
| 
 | ||||
| use core\entities\user\User; | ||||
| use Yii; | ||||
| use yii\helpers\FileHelper; | ||||
| use yii\imagine\Image; | ||||
| use yii\web\NotFoundHttpException; | ||||
| 
 | ||||
| class AvatarGenerator | ||||
| { | ||||
|     public $originPath; | ||||
|     public $cachePath; | ||||
| 
 | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->originPath = Yii::getAlias('@staticRoot') . '/origin'; | ||||
|         $this->cachePath = Yii::getAlias('@staticRoot') . '/cache'; | ||||
|     } | ||||
| 
 | ||||
| 	/** | ||||
| 	 * @param string $type | ||||
| 	 * @param string $name | ||||
| 	 * @param array|null $options | ||||
| 	 * | ||||
| 	 * @return string | ||||
| 	 * @throws NotFoundHttpException | ||||
| 	 * @throws \yii\base\Exception | ||||
| 	 */ | ||||
|     public function image(string $type, string $name, array $options = null): string | ||||
|     { | ||||
|         $originPath = $this->originPath . '/' . $type; | ||||
|         $origin = $originPath . '/' . $name; | ||||
| 
 | ||||
|         if (!file_exists($origin)) | ||||
|         { | ||||
|             return ''; | ||||
|         } | ||||
| 
 | ||||
|         $cachePath = $this->cachePath . '/' . $type; | ||||
|         $cache = $cachePath . '/' . (isset($options['newName']) ? $options['newName'] : $name); | ||||
| 
 | ||||
|         $cacheUrl = Yii::getAlias('@static')  . '/cache/' . $type . '/' . $name; | ||||
| 
 | ||||
|         if (isset($options['size'])) | ||||
|         { | ||||
|             $size = $options['size']; | ||||
|         } | ||||
| 
 | ||||
|         if (!isset($options['regenerate'])) | ||||
|         { | ||||
|             $options['regenerate'] = false; | ||||
|         } | ||||
| 
 | ||||
|         if (!file_exists($origin)) | ||||
|         { | ||||
|             throw new NotFoundHttpException('Image "' . $name . '" does not exists.'); | ||||
|         } | ||||
| 
 | ||||
|         if (!file_exists($cache) || $options['regenerate'] == true) | ||||
|         { | ||||
|             FileHelper::createDirectory($cachePath, 0755, true); | ||||
|             if (empty($size)) { | ||||
|                 //$size = isset(Yii::$app->params['imageSizes'][$type]) ? Yii::$app->params['imageSizes'][$type] : Yii::$app->params['imageSizes']['default']; | ||||
| 	            $size = [300, 300]; | ||||
|             } | ||||
|             Image::thumbnail($origin, $size[0], $size[1])->save($cache); | ||||
|         } | ||||
|         return $cacheUrl; | ||||
|     } | ||||
| 
 | ||||
|     public function avatar(int $id): string | ||||
|     { | ||||
|         if (!$user = User::findOne($id)) | ||||
|         { | ||||
|             throw new NotFoundHttpException('User does not exists.'); | ||||
|         } | ||||
|         if (empty($user->user_pic) || !file_exists($this->originPath . '/avatar/' . $user->user_pic)) | ||||
|         { | ||||
|             $user->user_pic = $this->generateAvatarByName($user->username); | ||||
|             $user->save(); | ||||
|         } | ||||
|         return $this->image('avatar', $user->user_pic); | ||||
|     } | ||||
| 
 | ||||
|     public function generateAvatarFromFile($file) | ||||
|     { | ||||
|         $fileName = md5('avatar-' . md5($file) . time()) . '.png'; | ||||
|         $originPath = $this->originPath . '/avatar'; | ||||
|         $origin = $originPath . '/' . $fileName; | ||||
|         FileHelper::createDirectory($originPath, 0755, true); | ||||
|         copy($file, $origin); | ||||
|         return $fileName; | ||||
|     } | ||||
| 
 | ||||
|     public function generateAvatarByName(string $name): string | ||||
|     { | ||||
|         $width = 300; | ||||
|         $height = 300; | ||||
|         $fontSize = 100; | ||||
| 	    $font = Yii::getAlias('@core') . '/components/avatar_generator/Play-Bold.ttf'; | ||||
| 
 | ||||
|         $parts = explode(' ', $name); | ||||
|         $text =  is_array($parts) && count($parts)>1 ? mb_substr($parts[0],0,1,"UTF-8") . mb_substr($parts[1],0,1,"UTF-8") : mb_substr($name,0,1,"UTF-8"); | ||||
| 
 | ||||
|         $fileName = md5('avatar-' . $name . time()) . '.png'; | ||||
| 
 | ||||
|         $originPath = $this->originPath . '/avatar'; | ||||
|         $origin = $originPath . '/' . $fileName; | ||||
| 
 | ||||
|         FileHelper::createDirectory($originPath, 0755, true); | ||||
| 
 | ||||
|         $img = imagecreatetruecolor($width, $height); | ||||
| 
 | ||||
|         $bgcolor = substr(md5($name), 0, 6); | ||||
| 
 | ||||
|         $rgb = []; | ||||
|         list($rgb['r'], $rgb['g'], $rgb['b']) = sscanf($bgcolor, "%02x%02x%02x"); | ||||
|         $rgb['rgb'] = $rgb['b'] + ($rgb['g'] << 0x8) + ($rgb['r'] << 0x10); | ||||
| 
 | ||||
|         $contrast = $this->RgbContrast($rgb['r'], $rgb['g'], $rgb['b']); | ||||
| 
 | ||||
|         $fillColor = imagecolorallocate($img, $rgb['r'], $rgb['g'], $rgb['b']); | ||||
|         imagefill($img, 0,0, $fillColor); | ||||
| 
 | ||||
|         $cor = imagecolorallocate($img, $contrast['r'], $contrast['g'], $contrast['b']); | ||||
| 
 | ||||
|         $box = imageftbbox( $fontSize, 0, $font, $text ); | ||||
|         $x = ($width - ($box[2] - $box[0])) / 2; | ||||
|         $y = ($height - ($box[1] - $box[7])) / 2; | ||||
|         $y -= $box[7]; | ||||
| 
 | ||||
|         imagettftext($img, $fontSize, 0, $x, $y, $cor, $font, $text); | ||||
|         imagepng($img, $origin); | ||||
|         imagedestroy($img); | ||||
|         return $fileName; | ||||
|     } | ||||
| 
 | ||||
|     public function getPath(string $type): string | ||||
|     { | ||||
|         if (!file_exists($this->originPath . '/' . $type)) | ||||
|         { | ||||
|             mkdir($this->originPath . '/' . $type, 0777, true); | ||||
|         } | ||||
|         return $this->originPath . '/' . $type; | ||||
|     } | ||||
| 
 | ||||
|     public function remove(string $type, string $fileName = null): void | ||||
|     { | ||||
|         if ($fileName && file_exists($this->originPath . '/' . $type . '/' . $fileName)) { | ||||
|             unlink($this->originPath . '/' . $type . '/' . $fileName); | ||||
|         } | ||||
| 
 | ||||
|         if ($fileName && file_exists($this->cachePath . '/' . $type . '/' . $fileName)) { | ||||
|             unlink($this->cachePath . '/' . $type . '/' . $fileName); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public function RgbContrast($r, $g, $b) { | ||||
|         return array( | ||||
|             'r' => ($r < 128) ? 255 : 0, | ||||
|             'g' => ($g < 128) ? 255 : 0, | ||||
|             'b' => ($b < 128) ? 255 : 0 | ||||
|         ); | ||||
|     } | ||||
| } | ||||
									
										Binary file not shown.
									
								
							
						| @ -0,0 +1,81 @@ | ||||
| ### Модули | ||||
| 
 | ||||
| Модули располагаются в папке `common/modules` | ||||
| 
 | ||||
| Папка модуля должна содержать основной файл, например, `BlogModule.php` следующего содержания | ||||
| ```php | ||||
| <?php | ||||
| 
 | ||||
| namespace common\modules\blog; | ||||
| use core\components\modules\ModuleInterface; | ||||
| use yii\helpers\ArrayHelper; | ||||
| 
 | ||||
| class BlogModule extends \yii\base\Module implements ModuleInterface | ||||
| { | ||||
|     // Папка контроллеров модуля | ||||
|     public $controllerNamespace = 'common\modules\blog\controllers'; | ||||
| 
 | ||||
|     // Инициализация модуля | ||||
|     public function init() | ||||
|     { | ||||
|         parent::init(); | ||||
|         // custom initialization code goes here | ||||
|     } | ||||
| 
 | ||||
|     // Автозапуск модуля | ||||
| 	public function bootstrap($app) | ||||
| 	{ | ||||
| 		// Добавление правила поиска по данному модулю | ||||
| 		$app->params['search_rules'][] = "SELECT title, content, CONCAT('/blog/manage/post/view/', id) AS url FROM {{blog_posts}}"; | ||||
| 		 | ||||
| 		// Добавление правила роутинга | ||||
| 		$app->getUrlManager()->addRules([ | ||||
| 			'blog' => 'blog/post/index', | ||||
| 		]); | ||||
| 
 | ||||
|         // Добавление правил роутинга, в случае использования классов | ||||
| 		$app->getUrlManager()->addRules([ | ||||
| 			['class' => 'common\modules\blog\urls\BlogPostUrlRule'], | ||||
| 			['class' => 'common\modules\blog\urls\BlogCategoryUrlRule'], | ||||
| 		]); | ||||
| 
 | ||||
| 		// Добавление локализации | ||||
| 		$app->getI18n()->translations = ArrayHelper::merge($app->getI18n()->translations, [ | ||||
| 			'blog' => [ | ||||
| 				'class' => 'yii\i18n\PhpMessageSource', | ||||
| 				'basePath' => '@common/modules/blog/messages', | ||||
| 			], | ||||
| 			'blog_public' => [ | ||||
| 				'class' => 'yii\i18n\PhpMessageSource', | ||||
| 				'basePath' => '@common/modules/blog/messages', | ||||
| 			], | ||||
| 		]); | ||||
| 		 | ||||
|         // Добавление пунктов в меню администратора | ||||
| 		if (basename($app->getBasePath()) === 'backend') { | ||||
| 			$app->params['adminMenu'][] = [ | ||||
| 				'label'   => \Yii::t( 'blog', 'Blog' ), | ||||
| 				'icon'    => 'book', | ||||
| 				'items'   => [ | ||||
| 					[ | ||||
| 						'label' => \Yii::t( 'blog', 'Categories' ), | ||||
| 						'icon'  => 'caret-right', | ||||
| 						'url'   => [ '/blog/manage/category/index' ] | ||||
| 					], | ||||
| 					[ | ||||
| 						'label' => \Yii::t( 'blog', 'Posts' ), | ||||
| 						'icon'  => 'caret-right', | ||||
| 						'url'   => [ '/blog/manage/post/index' ] | ||||
| 					], | ||||
| 					[ | ||||
| 						'label' => \Yii::t( 'blog', 'Comments' ), | ||||
| 						'icon'  => 'caret-right', | ||||
| 						'url'   => [ '/blog/manage/comment/index' ] | ||||
| 					], | ||||
| 				], | ||||
| 				'visible' => \Yii::$app->user->can( 'admin' ) || \Yii::$app->user->can( 'BlogManagement' ) | ||||
| 			]; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| ``` | ||||
| @ -0,0 +1,18 @@ | ||||
| # Zertex CMS | ||||
| Система управления сайтом на Yii2 | ||||
| 
 | ||||
| **Для разработчика** | ||||
| 
 | ||||
| * [Модули](Modules.md) | ||||
| 
 | ||||
| #### Дополнительные параметры Yii::$app | ||||
| 
 | ||||
| 1. `$app->params['search_rules']` - Массив правил для поиска. | ||||
| 
 | ||||
| Пример: | ||||
| ```php | ||||
| $app->params['search_rules'][] = "SELECT title, content, CONCAT('/blog/manage/post/view/', id) AS url FROM {{blog_posts}}"; | ||||
| ```  | ||||
| Поиск осуществляется по полям TITLE и CONTENT. В качестве URL указывается ссылка на конкрутную запись. | ||||
| 
 | ||||
| Если название полей отличаются от TITLE и CONTENT, но, сгласно правилам SQL, указывайте ваше поле, затем `as TITLE` или `as CONTENT` | ||||
					Loading…
					
					
				
		Reference in new issue