Commit 3735dff7ee125b66a7cacbcc27a8343e1125c292

Authored by Yarik
1 parent e75f77a6

test

common/config/bootstrap.php
1 1 <?php
2   -Yii::setAlias('common', dirname(__DIR__));
3   -Yii::setAlias('frontend', dirname(dirname(__DIR__)) . '/frontend');
4   -Yii::setAlias('backend', dirname(dirname(__DIR__)) . '/backend');
5   -Yii::setAlias('console', dirname(dirname(__DIR__)) . '/console');
6   -Yii::setAlias('saveImageDir', '@frontend/web/images/upload/');
7   -Yii::setAlias('storage', dirname(dirname(__DIR__)) . '/storage');
  2 + Yii::setAlias('common', dirname(__DIR__));
  3 + Yii::setAlias('frontend', dirname(dirname(__DIR__)) . '/frontend');
  4 + Yii::setAlias('backend', dirname(dirname(__DIR__)) . '/backend');
  5 + Yii::setAlias('console', dirname(dirname(__DIR__)) . '/console');
  6 + Yii::setAlias('saveImageDir', '@frontend/web/images/upload/');
  7 + Yii::setAlias('storage', dirname(dirname(__DIR__)) . '/storage');
  8 + Yii::setAlias('documentRoot', dirname(dirname(__DIR__)));
... ...
common/config/main.php
1 1 <?php
2 2  
  3 + use common\modules\fileloader\controllers\FileloaderController;
  4 +
3 5 return [
4 6 'timeZone' => 'Europe/Kiev',
5 7 'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
... ... @@ -28,6 +30,9 @@
28 30 'artbox-comment' => [
29 31 'class' => \common\modules\comment\Controller::className(),
30 32 ],
  33 + 'fileloader' => [
  34 + 'class' => FileloaderController::className(),
  35 + ],
31 36 ],
32 37  
33 38 'modules' => [
... ...
common/models/Project.php
... ... @@ -3,9 +3,12 @@
3 3 namespace common\models;
4 4  
5 5 use common\modules\comment\models\CommentProject;
  6 + use common\modules\fileloader\behaviors\FileloaderBehavior;
  7 + use common\modules\fileloader\models\Fileloader;
6 8 use Yii;
7 9 use yii\behaviors\BlameableBehavior;
8 10 use yii\behaviors\TimestampBehavior;
  11 + use yii\db\ActiveQuery;
9 12 use yii\db\Expression;
10 13  
11 14 /**
... ... @@ -33,6 +36,8 @@
33 36 * @property Currency $budgetCurrency
34 37 * @property Project $parent
35 38 * @property int $hidden
  39 + * @property int[] $fileloader
  40 + * @method File[] getFileloaderFiles()
36 41 */
37 42 class Project extends \yii\db\ActiveRecord
38 43 {
... ... @@ -64,12 +69,15 @@
64 69 'updatedAtAttribute' => false,
65 70 'value' => new Expression('NOW()'),
66 71 ],
67   - 'slug' => [
  72 + 'slug' => [
68 73 'class' => 'common\behaviors\Slug',
69 74 'in_attribute' => 'name',
70 75 'out_attribute' => 'link',
71 76 'translit' => true,
72 77 ],
  78 + 'fileloader' => [
  79 + 'class' => FileloaderBehavior::className(),
  80 + ],
73 81 ];
74 82 }
75 83  
... ... @@ -154,21 +162,21 @@
154 162 'boolean',
155 163 ],
156 164 [
157   - ['hidden'],
  165 + [ 'hidden' ],
158 166 'default',
159 167 'value' => 0,
160 168 ],
161 169 [
162   - ['date_end'],
  170 + [ 'date_end' ],
163 171 'filter',
164 172 'filter' => function($value) {
165 173 $unix = strtotime($value);
166 174 if($unix <= time()) {
167   - $unix = time() + (3600 * 24 * 7);
  175 + $unix = time() + ( 3600 * 24 * 7 );
168 176 }
169 177 return date('Y-m-d', $unix);
170   - }
171   - ]
  178 + },
  179 + ],
172 180 ];
173 181 }
174 182  
... ... @@ -332,4 +340,5 @@
332 340 return $this->hasMany(CommentProject::className(), [ 'model_id' => 'project_id' ])
333 341 ->andWhere([ 'model' => $this->className() ]);
334 342 }
  343 +
335 344 }
... ...
common/modules/fileloader/Module.php 0 → 100644
  1 +<?php
  2 + namespace common\modules\fileloader;
  3 +
  4 + /**
  5 + * Class Module
  6 + * @package common\modules\comment
  7 + */
  8 + class Module extends \yii\base\Module
  9 + {
  10 +
  11 + /**
  12 + * @var string Module name
  13 + */
  14 + public static $moduleName = 'artbox_fileloader';
  15 +
  16 + /**
  17 + * @inheritdoc
  18 + */
  19 + public function init()
  20 + {
  21 + parent::init();
  22 + }
  23 + }
0 24 \ No newline at end of file
... ...
common/modules/fileloader/assets/FileloaderAsset.php 0 → 100644
  1 +<?php
  2 + namespace common\modules\fileloader\assets;
  3 +
  4 + use yii\web\View;
  5 +
  6 + class FileloaderAsset extends \yii\web\AssetBundle
  7 + {
  8 +
  9 + public $sourcePath = '@common/modules/fileloader/resources';
  10 +
  11 + public $css = [
  12 + 'fileloader.css',
  13 + ];
  14 +
  15 + public $js = [
  16 + 'jquery.ui.widget.js',
  17 + 'jquery.fileupload.js',
  18 + 'jquery.iframe-transport.js',
  19 + 'handler.js',
  20 + ];
  21 +
  22 + public $depends = [
  23 + '\yii\web\YiiAsset',
  24 + '\yii\web\JqueryAsset',
  25 + '\yii\bootstrap\BootstrapAsset',
  26 + ];
  27 +
  28 + public $jsOptions = [
  29 + 'position' => View::POS_HEAD,
  30 + ];
  31 +
  32 + }
0 33 \ No newline at end of file
... ...
common/modules/fileloader/behaviors/FileloaderBehavior.php 0 → 100644
  1 +<?php
  2 + namespace common\modules\fileloader\behaviors;
  3 +
  4 + use yii\base\Behavior;
  5 + use yii\base\Event;
  6 + use yii\db\ActiveQuery;
  7 + use yii\db\ActiveRecord;
  8 + use yii\validators\Validator;
  9 +
  10 + /**
  11 + * Class FileloaderBehavior
  12 + * @package common\modules\fileloader\behaviors
  13 + */
  14 + class FileloaderBehavior extends Behavior
  15 + {
  16 +
  17 + /**
  18 + * @var string $fileclass Classname that hande files
  19 + */
  20 + public $fileclass = 'common\models\File';
  21 +
  22 + /**
  23 + * @var string $relationtable Table name that keeps relation between model and file
  24 + */
  25 + public $relationclass = 'common\modules\fileloader\models\FileRelation';
  26 +
  27 + /**
  28 + * @var int[] Files ids to insert
  29 + */
  30 + public $fileloader = [ ];
  31 +
  32 + /**
  33 + * @inheritdoc
  34 + */
  35 + public function events()
  36 + {
  37 + return [
  38 + ActiveRecord::EVENT_AFTER_INSERT => 'afterSave',
  39 + ActiveRecord::EVENT_AFTER_UPDATE => 'afterSave',
  40 + ActiveRecord::EVENT_INIT => 'attachValidator',
  41 + ];
  42 + }
  43 +
  44 + public function attachValidator($event)
  45 + {
  46 + $validator = Validator::createValidator('safe', $this->owner, 'fileloader');
  47 + $this->owner->validators->append($validator);
  48 + }
  49 +
  50 + /**
  51 + * After saving model delete all relative files and insert new file connections from
  52 + * fileloader variable
  53 + *
  54 + * @param Event $event
  55 + */
  56 + public function afterSave($event)
  57 + {
  58 + /**
  59 + * @var ActiveRecord $owner
  60 + * @var string $relation
  61 + */
  62 + $owner = $this->owner;
  63 + $relation = $this->relationclass;
  64 + call_user_func([
  65 + $relation,
  66 + 'deleteAll',
  67 + ], [
  68 + 'model' => $owner->className(),
  69 + 'model_id' => $owner->primaryKey,
  70 + ]);
  71 + if(!empty( $owner->fileloader )) {
  72 + foreach($owner->fileloader as $file) {
  73 + /**
  74 + * @var ActiveRecord $model
  75 + */
  76 + $model = new $relation([
  77 + 'file_id' => $file,
  78 + 'model' => $owner->className(),
  79 + 'model_id' => $owner->primaryKey,
  80 + 'user_id' => \Yii::$app->user->getId(),
  81 + 'status' => 1,
  82 + ]);
  83 + if($model->validate()) {
  84 + $model->save(false);
  85 + }
  86 + unset( $model );
  87 + }
  88 + }
  89 + }
  90 +
  91 + /**
  92 + * Bind owner class tp specified $fileclass via $relationclass table.
  93 + * @return ActiveQuery
  94 + */
  95 + public function getFileloaderFiles()
  96 + {
  97 + /**
  98 + * @var ActiveRecord $owner
  99 + */
  100 + $owner = $this->owner;
  101 + $relationtable = call_user_func([
  102 + $this->relationclass,
  103 + 'tableName',
  104 + ]);
  105 + return $owner->hasMany($this->fileclass, [ 'file_id' => 'file_id' ])
  106 + ->viaTable($relationtable, [ 'model_id' => $owner->primaryKey()[ 0 ] ], function($query) use ($owner) {
  107 + /**
  108 + * @var ActiveQuery $query
  109 + */
  110 + $query->andWhere([
  111 + 'model' => $owner->className(),
  112 + 'status' => 1,
  113 + ]);
  114 + });
  115 + }
  116 + }
0 117 \ No newline at end of file
... ...
common/modules/fileloader/controllers/FileloaderController.php 0 → 100644
  1 +<?php
  2 + namespace common\modules\fileloader\controllers;
  3 +
  4 + use common\modules\fileloader\models\Fileloader;
  5 + use yii\filters\AccessControl;
  6 + use yii\helpers\Html;
  7 + use yii\web\UploadedFile;
  8 +
  9 + class FileloaderController extends \yii\web\Controller
  10 + {
  11 +
  12 + /**
  13 + * @inheritdoc
  14 + */
  15 + public function behaviors()
  16 + {
  17 + return [
  18 + 'access' => [
  19 + 'class' => AccessControl::className(),
  20 + 'rules' => [
  21 + [
  22 + 'allow' => true,
  23 + 'roles' => [ '@' ],
  24 + ],
  25 + ],
  26 + ],
  27 + 'verbs' => [
  28 + 'class' => \yii\filters\VerbFilter::className(),
  29 + 'actions' => [
  30 + '*' => [ 'post' ],
  31 + ],
  32 + ],
  33 + ];
  34 + }
  35 +
  36 + /**
  37 + * Handle ajax file uploading
  38 + *
  39 + * @return array
  40 + */
  41 + public function actionUpload()
  42 + {
  43 + $request = \Yii::$app->request;
  44 + $response = \Yii::$app->response;
  45 + $response->format = $response::FORMAT_JSON;
  46 + $model = new Fileloader();
  47 + $model->files = UploadedFile::getInstance($model, 'files');
  48 + if(!empty( $model->files )) {
  49 + $file_id = $model->saveFile($model->files);
  50 + if(!empty( $file_id )) {
  51 + $child_model = $request->post('model', $model->className());
  52 + $child_model = new $child_model([ 'file' => $file_id ]);
  53 + $input = Html::activeHiddenInput($child_model, 'fileloader[]', [
  54 + 'value' => $file_id,
  55 + 'class' => 'fileloader-item-input',
  56 + ]);
  57 + return [
  58 + 'result' => [
  59 + 'file_id' => $file_id,
  60 + 'file_name' => $model->name,
  61 + 'file_href' => $model->dir,
  62 + 'input' => $input,
  63 + 'id' => $request->post('id'),
  64 + ],
  65 + ];
  66 + } else {
  67 + return [ 'error' => 'Ошибка сохранения файла' ];
  68 + }
  69 + }
  70 + return [ 'error' => 'Ошибка загрузки' ];
  71 + }
  72 +
  73 + /**
  74 + * Handle ajax file deleting
  75 + *
  76 + * @return array
  77 + */
  78 + public function actionDelete()
  79 + {
  80 + /**
  81 + * @var Fileloader $model
  82 + */
  83 + $request = \Yii::$app->request;
  84 + $response = \Yii::$app->response;
  85 + $response->format = $response::FORMAT_JSON;
  86 + if(empty( $request->post('id') )) {
  87 + return [ 'error' => 'Не указан id файла' ];
  88 + }
  89 + $model = Fileloader::find()
  90 + ->where([
  91 + 'file_id' => $request->post('id'),
  92 + 'user_id' => \Yii::$app->user->getId(),
  93 + ])
  94 + ->one();
  95 + if(empty( $model )) {
  96 + return [ 'error' => 'Файл не найден' ];
  97 + }
  98 + if($model->delete()) {
  99 + return [ 'result' => [ 'message' => 'Файл успешно удален' ] ];
  100 + } else {
  101 + return [ 'error' => 'Ошибка удаления файла' ];
  102 + }
  103 + }
  104 +
  105 + }
0 106 \ No newline at end of file
... ...
common/modules/fileloader/models/FileRelation.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace common\modules\fileloader\models;
  4 +
  5 +use common\models\File;
  6 +use common\models\User;
  7 +use Yii;
  8 +
  9 +/**
  10 + * This is the model class for table "file_relation".
  11 + *
  12 + * @property integer $file_relation_id
  13 + * @property integer $file_id
  14 + * @property string $model
  15 + * @property integer $model_id
  16 + * @property integer $user_id
  17 + * @property string $date_add
  18 + * @property integer $status
  19 + *
  20 + * @property File $file
  21 + * @property User $user
  22 + */
  23 +class FileRelation extends \yii\db\ActiveRecord
  24 +{
  25 + /**
  26 + * @inheritdoc
  27 + */
  28 + public static function tableName()
  29 + {
  30 + return 'file_relation';
  31 + }
  32 +
  33 + /**
  34 + * @inheritdoc
  35 + */
  36 + public function rules()
  37 + {
  38 + return [
  39 + [['file_id', 'model', 'model_id'], 'required'],
  40 + [['file_id', 'model_id', 'user_id', 'status'], 'integer'],
  41 + [['date_add'], 'safe'],
  42 + [['model'], 'string', 'max' => 255],
  43 + [['file_id'], 'exist', 'skipOnError' => true, 'targetClass' => File::className(), 'targetAttribute' => ['file_id' => 'file_id']],
  44 + [['user_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['user_id' => 'id']],
  45 + ];
  46 + }
  47 +
  48 + /**
  49 + * @inheritdoc
  50 + */
  51 + public function attributeLabels()
  52 + {
  53 + return [
  54 + 'file_relation_id' => Yii::t('app', 'File Relation ID'),
  55 + 'file_id' => Yii::t('app', 'File ID'),
  56 + 'model' => Yii::t('app', 'Model'),
  57 + 'model_id' => Yii::t('app', 'Model ID'),
  58 + 'user_id' => Yii::t('app', 'User ID'),
  59 + 'date_add' => Yii::t('app', 'Date Add'),
  60 + 'status' => Yii::t('app', 'Status'),
  61 + ];
  62 + }
  63 +
  64 + /**
  65 + * @return \yii\db\ActiveQuery
  66 + */
  67 + public function getFile()
  68 + {
  69 + return $this->hasOne(File::className(), ['file_id' => 'file_id']);
  70 + }
  71 +
  72 + /**
  73 + * @return \yii\db\ActiveQuery
  74 + */
  75 + public function getUser()
  76 + {
  77 + return $this->hasOne(User::className(), ['id' => 'user_id']);
  78 + }
  79 +}
... ...
common/modules/fileloader/models/Fileloader.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace common\modules\fileloader\models;
  4 +
  5 +use common\models\Tools;
  6 +use Yii;
  7 +use yii\behaviors\BlameableBehavior;
  8 +use yii\web\UploadedFile;
  9 +
  10 +/**
  11 + * This is the model class for table "file".
  12 + *
  13 + * @property integer $file_id
  14 + * @property integer $status
  15 + * @property string $name
  16 + * @property string $dir
  17 + */
  18 +class Fileloader extends \yii\db\ActiveRecord
  19 +{
  20 + public $files;
  21 + /**
  22 + * @inheritdoc
  23 + */
  24 + public static function tableName()
  25 + {
  26 + return 'file';
  27 + }
  28 +
  29 + /**
  30 + * @inheritdoc
  31 + */
  32 + public function behaviors()
  33 + {
  34 + return [
  35 + [
  36 + 'class' => BlameableBehavior::className(),
  37 + 'createdByAttribute' => 'user_id',
  38 + 'updatedByAttribute' => false,
  39 + ],
  40 + ];
  41 + }
  42 +
  43 + /**
  44 + * @inheritdoc
  45 + */
  46 + public function rules()
  47 + {
  48 + return [
  49 + [['status'], 'integer'],
  50 + [['name'], 'string', 'max' => 50],
  51 + [['dir'], 'string', 'max' => 255],
  52 + ];
  53 + }
  54 +
  55 + /**
  56 + * @inheritdoc
  57 + */
  58 + public function attributeLabels()
  59 + {
  60 + return [
  61 + 'file_id' => 'File ID',
  62 + 'status' => 'Status',
  63 + 'name' => 'Name',
  64 + 'dir' => 'Dir',
  65 + ];
  66 + }
  67 +
  68 + /**
  69 + * @param UploadedFile $file
  70 + * @return int file id in model File
  71 + */
  72 + public function saveFile(UploadedFile $file){
  73 + $imgDir = Yii::getAlias('@storage/'.'user_'.\Yii::$app->user->id.'/files/');
  74 + $uploadName = preg_replace('/\s/', '_', $file->baseName).'_'. time().'.'.$file->extension;
  75 + $uploadName = Tools::translit($uploadName, 'letter');
  76 + if(!is_dir($imgDir)) {
  77 + mkdir($imgDir, 0755, true);
  78 + }
  79 + if($file->saveAs($imgDir.$uploadName)){
  80 + $this->dir = '/storage/user_'.\Yii::$app->user->id.'/files/'.$uploadName;
  81 + $this->name = preg_replace('/\s/', '_', $file->baseName).'.'.$file->extension;
  82 + $this->save();
  83 + return $this->file_id;
  84 + }
  85 + }
  86 +
  87 + /**
  88 + * Extends ActiveRecord::delete() method, also deletes file from file system
  89 + *
  90 + * @see ActiveRecord::delete()
  91 + * @return false|int
  92 + * @throws \Exception
  93 + */
  94 + public function delete()
  95 + {
  96 + if(!empty($this->dir)) {
  97 + if(file_exists(Yii::getAlias('@documentRoot').$this->dir)) {
  98 + unlink(Yii::getAlias('@documentRoot').$this->dir);
  99 + }
  100 + }
  101 + return parent::delete();
  102 + }
  103 +}
... ...
common/modules/fileloader/resources/fileloader.css 0 → 100644
  1 +.fileloader-item-name {
  2 + display: inline-block;
  3 +}
  4 +.fileloader-item-name a {
  5 + text-decoration: none;
  6 + border-bottom: dotted 1px;
  7 +}
  8 +.fileloader-item-name a:hover, .fileloader-item-name a:focus {
  9 + text-decoration: none;
  10 +}
  11 +.fileloader-item-remove {
  12 + padding-left: 10px;
  13 + cursor: pointer;
  14 +}
  15 +.fileloader-file {
  16 + position: relative;
  17 +}
0 18 \ No newline at end of file
... ...
common/modules/fileloader/resources/handler.js 0 → 100644
  1 +$(function() {
  2 + if(fileloader !== undefined) {
  3 + $.each(fileloader, function(index, value) {
  4 + var id = value.id;
  5 + var model = value.model;
  6 + var formData = {};
  7 + if(typeof model == 'string' && model !== '') {
  8 + formData.model = model;
  9 + }
  10 + if(typeof id == 'string' && id !== '') {
  11 + formData.id = id;
  12 + $('#'+id).fileupload({
  13 + dataType: 'json',
  14 + url: '/fileloader/upload',
  15 + formData: formData,
  16 + done: function(e, data) {
  17 + if(!data.result.error) {
  18 + var id = data.result.result.id;
  19 + var input = $('#'+id);
  20 + var wrapper = $(input).parents('.fileloader-wrapper').first();
  21 + var html = '<div class="fileloader-item-wrapper" data-id="'+data.result.result.file_id+'">'+
  22 + data.result.result.input + '<p class="fileloader-item-name">'+
  23 + '<a href="'+data.result.result.file_href+'" target="_blank">'+data.result.result.file_name+'</a></p>'+'<span class="fileloader-item-remove glyphicon glyphicon-remove"></span>'+
  24 + '</div>';
  25 + $(html).appendTo($(wrapper).find('.fileloader-list'));
  26 + }
  27 + }
  28 + });
  29 + }
  30 + });
  31 + }
  32 +
  33 + $(document).on('click', '.fileloader-item-remove', function(e) {
  34 + var wrapper = $(this).parents('.fileloader-item-wrapper').first();
  35 + var id = $(wrapper).data('id');
  36 + $.post(
  37 + '/fileloader/delete',
  38 + {
  39 + id: id
  40 + },
  41 + function(data) {}
  42 + );
  43 + $(wrapper).remove();
  44 + });
  45 +});
... ...
common/modules/fileloader/widgets/FileloaderWidget.php 0 → 100644
  1 +<?php
  2 + namespace common\modules\fileloader\widgets;
  3 +
  4 + use common\modules\fileloader\assets\FileloaderAsset;
  5 + use common\modules\fileloader\behaviors\FileloaderBehavior;
  6 + use common\modules\fileloader\models\Fileloader;
  7 + use yii\db\ActiveRecord;
  8 + use yii\helpers\ArrayHelper;
  9 + use \yii\helpers\Html;
  10 + use yii\web\View;
  11 +
  12 + /**
  13 + * Class FileloaderWidget
  14 + * @package common\modules\fileloader\widgets
  15 + */
  16 + class FileloaderWidget extends \yii\base\Widget
  17 + {
  18 +
  19 + /**
  20 + * @var array $labelOptions Label options.
  21 + * <i>Special: 1. You cannot modify 'for' attribute</i>
  22 + */
  23 + public $labelOptions = [ ];
  24 +
  25 + /**
  26 + * @var array $inputOptions Input options.
  27 + * <i>
  28 + * Special:
  29 + * 1. You cannot modify 'id' attribute.
  30 + * 2. Class will be appended by base input class
  31 + * <i>
  32 + */
  33 + public $inputOptions = [ ];
  34 +
  35 + /**
  36 + * @var array $hintOptions Hint options.
  37 + * <i>
  38 + * 1. tag will be used to generate container tag. Default to 'div'
  39 + * 2. value will be used to generate content. If missing, component won't be rendered
  40 + * </i>
  41 + */
  42 + public $hintOptions = [ ];
  43 +
  44 + /**
  45 + * @var array $errorOptions Error options
  46 + * <i>
  47 + * 1. tag will be used to generate container tag. Default to 'div'
  48 + * 2. class will be appended by base error class
  49 + * </i>
  50 + */
  51 + public $errorOptions = [ ];
  52 +
  53 + /**
  54 + * @var array $listOptions Items list options
  55 + * <i>
  56 + * 1. tag will be used to generate container tag. Default to 'div'
  57 + * 2. class will be appended by base list class
  58 + * </i>
  59 + */
  60 + public $listOptions = [ ];
  61 +
  62 + /**
  63 + * @var array $options Container options
  64 + * <i>
  65 + * 1. tag will be used to generate container tag. Default to 'div'
  66 + * 2. class will be appended by base wrapper class
  67 + * </i>
  68 + */
  69 + public $options = [ ];
  70 +
  71 + /**
  72 + * @var ActiveRecord $model Model where to insert files
  73 + */
  74 + public $model;
  75 +
  76 + /**
  77 + * @var string $attribute Model attribute
  78 + */
  79 + public $attribute;
  80 +
  81 + /**
  82 + * @var View $view Current view object
  83 + */
  84 + public $view;
  85 +
  86 + /**
  87 + * @var string $template Widget template. Recognised components: {label}, {input}, {hint},
  88 + * {error}, {list}
  89 + */
  90 + public $template = '{label}{input}{hint}{error}{list}';
  91 +
  92 + /**
  93 + * @var bool $displayLabel Whether to display label component or not
  94 + */
  95 + public $displayLabel = true;
  96 +
  97 + /**
  98 + * @var bool $displayInput Whether to display input component or not
  99 + */
  100 + public $displayInput = true;
  101 +
  102 + /**
  103 + * @var bool $displayHint Whether to display hint component or not
  104 + */
  105 + public $displayHint = true;
  106 +
  107 + /**
  108 + * @var bool $displayError Whether to display error component or not
  109 + */
  110 + public $displayError = true;
  111 +
  112 + /**
  113 + * @var bool $displayList Whether to display list component or not
  114 + */
  115 + public $displayList = true;
  116 +
  117 + protected $label = '';
  118 +
  119 + protected $input = '';
  120 +
  121 + protected $hint = '';
  122 +
  123 + protected $error = '';
  124 +
  125 + protected $list = '';
  126 +
  127 + /**
  128 + * @var string Unique widget ID
  129 + */
  130 + protected $inputID;
  131 +
  132 + /**
  133 + * @var Fileloader $fileloader Fileloader model
  134 + */
  135 + protected $fileloader;
  136 +
  137 + protected $output = '';
  138 +
  139 + /**
  140 + * @var string $baseClass Will be added to input component
  141 + */
  142 + protected $baseClass = ' fileloader-input';
  143 +
  144 + /**
  145 + * @var string $baseErrorClass Will be added to error container
  146 + */
  147 + protected $baseErrorClass = ' fileloader-error';
  148 +
  149 + /**
  150 + * @var string $baseListClass Will be added to list container
  151 + */
  152 + protected $baseListClass = ' fileloader-list';
  153 +
  154 + /**
  155 + * @var string $baseWrapperClass Will be added to Container
  156 + */
  157 + protected $baseWrapperClass = ' fileloader-wrapper';
  158 +
  159 + /**
  160 + * @inheritdoc
  161 + */
  162 + public function init()
  163 + {
  164 + parent::init();
  165 + FileloaderAsset::register($this->view);
  166 + }
  167 +
  168 + /**
  169 + * @inheritdoc
  170 + * @return string
  171 + */
  172 + public function run()
  173 + {
  174 + $this->fileloader = new Fileloader();
  175 + $this->inputID = 'fileloader-' . $this->getId();
  176 + $this->createParts();
  177 + $this->output = $this->renderLoader();
  178 + $this->renderJS();
  179 + return $this->output;
  180 + }
  181 +
  182 + /**
  183 + * Fills widget components with data
  184 + */
  185 + public function createParts()
  186 + {
  187 + if(!empty( $this->displayLabel ) && preg_match('/^.*\{label\}.*$/i', $this->template)) {
  188 + $this->labelOptions[ 'for' ] = $this->inputID;
  189 + $this->label = Html::activeLabel($this->fileloader, 'files', $this->labelOptions);
  190 + }
  191 + if(!empty( $this->displayInput ) && preg_match('/^.*\{input\}.*$/i', $this->template)) {
  192 + if(empty( $this->inputOptions[ 'class' ] )) {
  193 + $this->inputOptions[ 'class' ] = $this->baseClass;
  194 + } else {
  195 + $this->inputOptions[ 'class' ] .= $this->baseClass;
  196 + }
  197 + $this->inputOptions[ 'id' ] = $this->inputID;
  198 + $this->input = Html::activeFileInput($this->fileloader, 'files', $this->inputOptions);
  199 + }
  200 + if(!empty( $this->displayHint ) && preg_match('/^.*\{hint\}.*$/i', $this->template) && !empty( $this->hintOptions[ 'value' ] )) {
  201 + $this->hint = Html::tag(ArrayHelper::remove($this->hintOptions, 'tag', 'div'), ArrayHelper::remove($this->hintOptions, 'value'), $this->hintOptions);
  202 + }
  203 + if(!empty( $this->displayError ) && preg_match('/^.*\{error\}.*$/i', $this->template)) {
  204 + if(empty( $this->errorOptions[ 'class' ] )) {
  205 + $this->errorOptions[ 'class' ] = $this->baseErrorClass;
  206 + } else {
  207 + $this->errorOptions[ 'class' ] .= $this->baseErrorClass;
  208 + }
  209 + $this->error = Html::tag(ArrayHelper::remove($this->errorOptions, 'tag', 'div'), '', $this->errorOptions);
  210 + }
  211 + if(!empty( $this->displayList ) && preg_match('/^.*\{list\}.*$/i', $this->template)) {
  212 + if(empty( $this->listOptions[ 'class' ] )) {
  213 + $this->listOptions[ 'class' ] = $this->baseListClass;
  214 + } else {
  215 + $this->listOptions[ 'class' ] .= $this->baseListClass;
  216 + }
  217 + $list = '';
  218 + $items = $this->getItems();
  219 + if(!empty( $items )) {
  220 + foreach($items as $item) {
  221 + $list .= '<div class="fileloader-item-wrapper" data-id="' . $item->file_id . '">' . Html::activeHiddenInput($this->model, 'fileloader[]', [
  222 + 'value' => $item->file_id,
  223 + 'class' => 'fileloader-item-input',
  224 + ]) . Html::tag('p', Html::a($item->name, $item->dir, [ 'target' => '_blank' ]), [
  225 + 'class' => 'fileloader-item-name',
  226 + ]) . Html::tag('span', '', [
  227 + 'class' => 'fileloader-item-remove glyphicon glyphicon-remove',
  228 + ]) . '</div>';
  229 + }
  230 + }
  231 + $this->list = Html::tag(ArrayHelper::remove($this->listOptions, 'tag', 'div'), $list, $this->listOptions);
  232 + }
  233 + }
  234 +
  235 + /**
  236 + * Fills template with components
  237 + * @return string
  238 + */
  239 + public function renderLoader()
  240 + {
  241 + $template = $this->template;
  242 + $template = preg_replace('/{label}/', $this->label, $template);
  243 + $template = preg_replace('/{input}/', $this->input, $template);
  244 + $template = preg_replace('/{hint}/', $this->hint, $template);
  245 + $template = preg_replace('/{error}/', $this->error, $template);
  246 + $template = preg_replace('/{list}/', $this->list, $template);
  247 + if(empty( $this->options[ 'class' ] )) {
  248 + $this->options[ 'class' ] = $this->baseWrapperClass;
  249 + } else {
  250 + $this->options[ 'class' ] .= $this->baseWrapperClass;
  251 + }
  252 + return Html::tag(ArrayHelper::remove($this->options, 'tag', 'div'), $template, $this->options);
  253 + }
  254 +
  255 + /**
  256 + * Get already set items
  257 + * @return ActiveRecord[]
  258 + */
  259 + public function getItems()
  260 + {
  261 + /**
  262 + * @var ActiveRecord $model
  263 + */
  264 + $model = $this->model;
  265 + if($behavior = $model->getBehavior('fileloader')) {
  266 + if($behavior instanceof FileloaderBehavior) {
  267 + return $model->getFileloaderFiles()
  268 + ->all();
  269 + } else {
  270 + return [ ];
  271 + }
  272 + } else {
  273 + return [ ];
  274 + }
  275 + }
  276 +
  277 + /**
  278 + * Render JS for widget
  279 + */
  280 + public function renderJS()
  281 + {
  282 + /**
  283 + * @var View $view
  284 + */
  285 + $view = $this->view;
  286 + $vars = json_encode([
  287 + 'id' => $this->inputID,
  288 + 'model' => $this->model->className(),
  289 + ]);
  290 + $js = "if(fileloader === undefined) {
  291 + var fileloader = [];
  292 + fileloader[0] = " . $vars . ";
  293 + } else {
  294 + fileloader[fileloader.length] = " . $vars . ";
  295 + }
  296 + ";
  297 + $view->registerJs($js, $view::POS_BEGIN);
  298 + }
  299 +
  300 + }
0 301 \ No newline at end of file
... ...
console/migrations/m160325_153328_file_relation_table.php 0 → 100644
  1 +<?php
  2 +
  3 + use yii\db\Migration;
  4 +
  5 + class m160325_153328_file_relation_table extends Migration
  6 + {
  7 +
  8 + public function up()
  9 + {
  10 + $this->createTable('{{%file_relation}}', [
  11 + 'file_relation_id' => $this->primaryKey(),
  12 + 'file_id' => $this->integer()
  13 + ->notNull(),
  14 + 'model' => $this->string()
  15 + ->notNull(),
  16 + 'model_id' => $this->integer()
  17 + ->notNull(),
  18 + 'user_id' => $this->integer(),
  19 + 'date_add' => $this->timestamp()
  20 + ->notNull()
  21 + ->defaultExpression('NOW()'),
  22 + 'status' => $this->smallInteger()
  23 + ->defaultValue(1),
  24 + ]);
  25 + $this->addForeignKey('file_relation_file', '{{%file_relation}}', 'file_id', '{{%file}}', 'file_id', 'CASCADE', 'CASCADE');
  26 + $this->addForeignKey('file_relation_user', '{{%file_relation}}', 'user_id', '{{%user}}', 'id', 'SET NULL', 'CASCADE');
  27 + }
  28 +
  29 + public function down()
  30 + {
  31 + $this->dropForeignKey('file_relation_file', '{{%file_relation}}');
  32 + $this->dropForeignKey('file_relation_user', '{{%file_relation}}');
  33 + $this->dropTable('{{%file_relation}}');
  34 + }
  35 + }
... ...
console/migrations/m160329_085324_file_add_user.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\db\Migration;
  4 +
  5 +class m160329_085324_file_add_user extends Migration
  6 +{
  7 + public function up()
  8 + {
  9 + $this->addColumn('{{%file}}', 'user_id', $this->integer());
  10 + $this->addForeignKey('file_user', '{{%file}}', 'user_id', '{{%user}}', 'id', 'SET DEFAULT', 'CASCADE');
  11 + }
  12 +
  13 + public function down()
  14 + {
  15 + $this->dropForeignKey('file_user', '{{%file}}');
  16 + $this->dropColumn('{{%file}}', 'user_id');
  17 + }
  18 +}
... ...
frontend/controllers/SiteController.php
... ... @@ -4,6 +4,7 @@ namespace frontend\controllers;
4 4 use common\models\Cities;
5 5 use common\models\CompanyInfo;
6 6 use common\models\Country;
  7 +use common\models\Project;
7 8 use common\models\Specialization;
8 9 use common\models\UserInfo;
9 10 use Faker\Provider\is_IS\Company;
... ...
frontend/views/accounts/_projects_form.php
... ... @@ -7,10 +7,12 @@
7 7 */
8 8 use common\components\Request;
9 9 use common\models\Currency;
  10 + use common\models\File;
10 11 use common\models\Payment;
11 12 use common\models\Project;
12 13 use common\models\Specialization;
13 14 use common\modules\file\widgets\ImageUploader;
  15 + use common\modules\fileloader\widgets\FileloaderWidget;
14 16 use kartik\select2\Select2;
15 17 use mihaildev\ckeditor\CKEditor;
16 18 use yii\helpers\Html;
... ... @@ -24,7 +26,7 @@
24 26 <div class="login-left-column-title"><?= $this->title ?></div>
25 27  
26 28 <?php
27   - $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]);
  29 + $form = ActiveForm::begin([ 'options' => [ 'enctype' => 'multipart/form-data' ] ]);
28 30 ?>
29 31  
30 32  
... ... @@ -212,43 +214,55 @@
212 214 </div>
213 215  
214 216 <?php
215   -/* == Здесь епты == */
216   -?>
217   -<div class="tender-file-wr">
218   - <?= $form->field($project, 'files[]')
219   - ->fileInput([ 'class' => 'multi', 'multiple' => 'multiple' ])
220   - ->label(false) ?>
221   - <a href="#" class="addfilemulti">Прикрепить файл</a>
222   - <div class="max-size">Максимальный размер<br/>файла 5 МБ</div>
223   -</div>
224   -<?php
225   -/* == .i. Конец епты .i. == */
226   -?>
227   -
228   -<div class="input-blocks-wrapper admin-project-file">
229   - <div class="input-blocks">
230   - <div style="position: absolute; float: left;top: 0; left: 0; z-index: 1; width: 100%; overflow: hidden">
231   - <div class="gen-admin-title">Присоединить файл</div>
232   - <div class="admin-project-file-btn">Загрузить</div>
233   - <div class="not-file-mb-adm">До 3 Мб файл</div>
234   - </div>
235   - <div style="opacity: 0; height: 54px; width: 100%; float: left;position: absolute; top: 0;left: 0; z-index: 2;-ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=0)'">
236   - <?= $form->field($project, 'files[]')
237   - ->fileInput([ 'multiple' => 'multiple' ]) ?>
  217 + /* == Old file upload ==
  218 + ?>
  219 + <div class="input-blocks-wrapper admin-project-file">
  220 + <div class="input-blocks">
  221 + <div style="position: absolute; float: left;top: 0; left: 0; z-index: 1; width: 100%; overflow: hidden">
  222 + <div class="gen-admin-title">Присоединить файл</div>
  223 + <div class="admin-project-file-btn">Загрузить</div>
  224 + <div class="not-file-mb-adm">До 3 Мб файл</div>
  225 + </div>
  226 + <div style="opacity: 0; height: 54px; width: 100%; float: left;position: absolute; top: 0;left: 0; z-index: 2;-ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=0)'">
  227 + <?= $form->field($project, 'files[]')
  228 + ->fileInput([ 'multiple' => 'multiple' ]) ?>
  229 + </div>
238 230 </div>
239   -
240 231 </div>
  232 + <?php
  233 + == End of old file upload == */
  234 +?>
  235 +
  236 +<div class="input-blocks-wrapper">
  237 + <?php
  238 + echo $form->field($project, 'fileloader')
  239 + ->label(false)
  240 + ->widget(FileloaderWidget::className(), [
  241 + 'labelOptions' => [ 'label' => '<div class="gen-admin-title">Присоединить файлы</div><div class="admin-project-file-btn">Загрузить</div><div class="not-file-mb-adm">До 3 Мб файл</div>' ],
  242 + 'inputOptions' => [
  243 + 'multiple' => 'multiple',
  244 + 'class' => 'hidden',
  245 + ],
  246 + 'options' => [ 'class' => 'fileloader-file' ],
  247 + ]);
  248 + ?>
241 249 </div>
242 250  
243 251 <div class="input-blocks-wrapper">
244 252 <div class="input-blocks admin-project-list admin-currency-second">
245   - <?= $form->field($project, 'date_end')->widget(DatePicker::className(), ['dateFormat' => 'yyyy-MM-dd', 'clientOptions' => ['minDate' => 1]]) ?>
  253 + <?= $form->field($project, 'date_end')
  254 + ->widget(DatePicker::className(), [
  255 + 'dateFormat' => 'yyyy-MM-dd',
  256 + 'clientOptions' => [ 'minDate' => 1 ],
  257 + ]) ?>
246 258 </div>
247 259 </div>
248 260  
249 261 <div class="input-blocks-wrapper">
250 262 <div class="input-blocks admin-project-list admin-currency-second">
251   - <?= $form->field($project, 'hidden')->checkbox()->hint('Проект, снятый с тендера, будет добавлен в Архив (не доступен в поиске, но доступен по ссылке)') ?>
  263 + <?= $form->field($project, 'hidden')
  264 + ->checkbox()
  265 + ->hint('Проект, снятый с тендера, будет добавлен в Архив (не доступен в поиске, но доступен по ссылке)') ?>
252 266 </div>
253 267 </div>
254 268  
... ...
frontend/views/layouts/performer.php
... ... @@ -22,7 +22,7 @@
22 22 <?php
23 23 if($this->params[ 'user' ]->id != \Yii::$app->user->getId()) {
24 24 // Offer project button
25   - if(!empty( $this->params[ 'type' ] ) && $this->params[ 'type' ] == 'customer') {
  25 + if(empty( $this->params[ 'type' ] ) || $this->params[ 'type' ] != 'customer') {
26 26 echo Html::a('Предложить проект', [ '#' ], [
27 27 'class' => 'blog-buttons-offer',
28 28 'data-performer-id' => $this->params[ 'user' ]->id,
... ...
frontend/views/site/index.php
1 1 <?php
2 2  
3   -use \yii\helpers\Html;
4   -use \common\models\Specialization;
5   -/**
6   - * @var $this yii\web\View
7   - * @var $specializations common\models\Specialization
8   - */
  3 + use common\models\Project;
  4 + use common\modules\fileloader\widgets\FileloaderWidget;
  5 + use \yii\helpers\Html;
  6 + use \common\models\Specialization;
  7 + use yii\widgets\ActiveForm;
9 8  
10   -$this->title = 'My Yii Application';
11   -?>
  9 + /**
  10 + * @var $this yii\web\View
  11 + * @var $specializations common\models\Specialization
  12 + */
12 13  
13   - <div class="section-box-1">
14   - <div class="box-wr">
15   - <div class="box-all">
16   - <div class="section-box-base">
17   - Самая полная база текущих и реализованных
18   - строительных проектов с исполнителями
19   - </div>
20   - <div class="section-box-base-block">
21   - <div class="base-blocks">
22   - <?= Html::a('Хочу заказать проект',['landing/landing-order-project'],['class'=>'base-blocks-button first_butt']) ?>
23   - <div class="base-blocks-text">
24   - <p>Лучшие компании и исполнители готовы помочь вам</p>
25   - </div>
  14 + $this->title = 'My Yii Application';
  15 +?>
  16 +<div class="section-box-1">
  17 + <div class="box-wr">
  18 + <div class="box-all">
  19 + <div class="section-box-base">
  20 + Самая полная база текущих и реализованных
  21 + строительных проектов с исполнителями
  22 + </div>
  23 + <div class="section-box-base-block">
  24 + <div class="base-blocks">
  25 + <?= Html::a('Хочу заказать проект', [ 'landing/landing-order-project' ], [ 'class' => 'base-blocks-button first_butt' ]) ?>
  26 + <div class="base-blocks-text">
  27 + <p>Лучшие компании и исполнители готовы помочь вам</p>
26 28 </div>
27   - <div class="base-blocks">
28   - <?= Html::a('Проектант/Фрилансер',['landing/landing-freelance'],['class'=>'base-blocks-button second_butt']) ?>
29   - <div class="base-blocks-text">
30   - <p>
31   - Частные проекты и субподряды от лучших компаний и заказчиков для вас
32   - </p>
33   - <p>
34   - <?= Html::a('Ищу работу',['landing/landing-work']) ?>
35   - Вакансии компаний и заказчиков на полную занятость и резюме свободных проектантов
36   - </p>
37   - </div>
  29 + </div>
  30 + <div class="base-blocks">
  31 + <?= Html::a('Проектант/Фрилансер', [ 'landing/landing-freelance' ], [ 'class' => 'base-blocks-button second_butt' ]) ?>
  32 + <div class="base-blocks-text">
  33 + <p>
  34 + Частные проекты и субподряды от лучших компаний и заказчиков для вас
  35 + </p>
  36 + <p>
  37 + <?= Html::a('Ищу работу', [ 'landing/landing-work' ]) ?>
  38 + Вакансии компаний и заказчиков на полную занятость и резюме свободных проектантов
  39 + </p>
38 40 </div>
39   - <div class="base-blocks">
40   - <?= Html::a('Представляю компанию',['landing/landing-company'], ['class'=>'base-blocks-button third_butt']) ?>
41   - <div class="base-blocks-text">
42   - <p>Презентуйте лучшую команду профессиональных проектантов и получите актуальные тендеры на проектирование.</p>
43   - </div>
  41 + </div>
  42 + <div class="base-blocks">
  43 + <?= Html::a('Представляю компанию', [ 'landing/landing-company' ], [ 'class' => 'base-blocks-button third_butt' ]) ?>
  44 + <div class="base-blocks-text">
  45 + <p>Презентуйте лучшую команду профессиональных проектантов и получите актуальные тендеры на проектирование.</p>
44 46 </div>
45 47 </div>
46 48 </div>
47 49 </div>
48 50 </div>
49   - <div class="section-box-2">
50   - <div class="box-wr">
51   - <div class="box-all">
52   - <div class="menu-two-wrapp-title">Специализация работ по исполнителям</div>
53   - <div class="menu-two-wrapp" style="background: url('/images/menu-pic-1.jpg') 100% 100% no-repeat">
54   - <ul class="content-menu-first">
55   - <?php foreach($specializations as $specialization):?>
56   - <li data-img="<?= $specialization->image?>">
57   - <span data-menu-bg="<?= $specialization->background ?>" style="background: <?= $specialization->background ?>"></span><a href="#"><?= $specialization->specialization_name?></a>
58   - <ul>
59   - <?php foreach($specialization->children as $child_first):?>
  51 +</div>
  52 +<div class="section-box-2">
  53 + <div class="box-wr">
  54 + <div class="box-all">
  55 + <div class="menu-two-wrapp-title">Специализация работ по исполнителям</div>
  56 + <div class="menu-two-wrapp" style="background: url('/images/menu-pic-1.jpg') 100% 100% no-repeat">
  57 + <ul class="content-menu-first">
  58 + <?php foreach($specializations as $specialization): ?>
  59 + <li data-img="<?= $specialization->image ?>">
  60 + <span data-menu-bg="<?= $specialization->background ?>" style="background: <?= $specialization->background ?>"></span><a href="#"><?= $specialization->specialization_name ?></a>
  61 + <ul>
  62 + <?php foreach($specialization->children as $child_first): ?>
60 63  
61   - <?php if($child_first instanceof Specialization):?>
62   - <li>
63   - <a href="#"><?= $child_first->specialization_name?></a>
64   - <ul>
65   - <?php foreach($child_first->children as $child_second):?>
66   - <?php if($child_first instanceof Specialization): ?>
67   - <li><a href="#"><?= $child_second->specialization_name?></a></li>
68   - <?php endif;?>
69   - <?php endforeach; ?>
70   - </ul>
71   - </li>
72   - <?php endif; ?>
73   - <?php endforeach; ?>
  64 + <?php if($child_first instanceof Specialization): ?>
  65 + <li>
  66 + <a href="#"><?= $child_first->specialization_name ?></a>
  67 + <ul>
  68 + <?php foreach($child_first->children as $child_second): ?>
  69 + <?php if($child_first instanceof Specialization): ?>
  70 + <li>
  71 + <a href="#"><?= $child_second->specialization_name ?></a>
  72 + </li>
  73 + <?php endif; ?>
  74 + <?php endforeach; ?>
  75 + </ul>
  76 + </li>
  77 + <?php endif; ?>
  78 + <?php endforeach; ?>
74 79  
75   - </ul>
76   - </li>
77   - <?php endforeach; ?>
78   - </ul>
79   - </div>
  80 + </ul>
  81 + </li>
  82 + <?php endforeach; ?>
  83 + </ul>
80 84 </div>
81 85 </div>
82 86 </div>
83   - <div class="section-box-3">
84   - <div class="box-wr">
85   - <div class="box-all">
86   - <div class="all-project-home-title_menu">
87   - <p>Проекты на нашем сайте</p>
88   - <ul>
89   - <li class="project-home-active"><span>Текущие</span></li>
90   - <li><span>Завершенные</span></li>
91   - </ul>
92   - </div>
  87 +</div>
  88 +<div class="section-box-3">
  89 + <div class="box-wr">
  90 + <div class="box-all">
  91 + <div class="all-project-home-title_menu">
  92 + <p>Проекты на нашем сайте</p>
  93 + <ul>
  94 + <li class="project-home-active"><span>Текущие</span></li>
  95 + <li><span>Завершенные</span></li>
  96 + </ul>
93 97 </div>
94 98 </div>
95   - <div class="section-box-map">
96   - <div class="shadow-map"></div>
97   - <div id="map_cloud" style="display: none;">
98   - <script type="text/javascript">
99   - function initialize() {
100   - var start_position = new google.maps.LatLng('56', '30');
101   - var settings = {
102   - zoom: 7,
103   - scrollwheel: false,
104   - center: start_position,
105   - mapTypeControl: false,
106   - mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
107   - navigationControl: false,
108   - navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
109   - scaleControl: false,
110   - streetViewControl: false,
111   - rotateControl: false,
112   - zoomControl:true,
113   - mapTypeId: google.maps.MapTypeId.ROADMAP};
114   - var map = new google.maps.Map(document.getElementById("map_canvas"), settings);
115   -
116   -
117   - var image1 = new google.maps.MarkerImage('/images/markers/marker-we-1.png',
118   - new google.maps.Size(21, 32),
119   - new google.maps.Point(0,0),
120   - new google.maps.Point(16, 35)
121   - );
122   - var image2 = new google.maps.MarkerImage('/images/markers/marker-we-2.png',
123   - new google.maps.Size(21, 32),
124   - new google.maps.Point(0,0),
125   - new google.maps.Point(16, 35)
126   - );
127   - var image3 = new google.maps.MarkerImage('/images/markers/marker-we-3.png',
128   - new google.maps.Size(21, 32),
129   - new google.maps.Point(0,0),
130   - new google.maps.Point(16, 35)
131   - );
132   - var image4 = new google.maps.MarkerImage('/images/markers/marker-we-4.png',
133   - new google.maps.Size(21, 32),
134   - new google.maps.Point(0,0),
135   - new google.maps.Point(16, 35)
136   - );
137   - var image5 = new google.maps.MarkerImage('/images/markers/marker-we-5.png',
138   - new google.maps.Size(21, 32),
139   - new google.maps.Point(0,0),
140   - new google.maps.Point(16, 35)
141   - );
142   - var image6 = new google.maps.MarkerImage('/images/markers/marker-we-6.png',
143   - new google.maps.Size(21, 32),
144   - new google.maps.Point(0,0),
145   - new google.maps.Point(16, 35)
146   - );
147   - var image7 = new google.maps.MarkerImage('/images/markers/marker-we-7.png',
148   - new google.maps.Size(21, 32),
149   - new google.maps.Point(0,0),
150   - new google.maps.Point(16, 35)
151   - );
152   - var image8 = new google.maps.MarkerImage('/images/markers/marker-we-8.png',
153   - new google.maps.Size(21, 32),
154   - new google.maps.Point(0,0),
155   - new google.maps.Point(16, 35)
156   - );
157   - var image9 = new google.maps.MarkerImage('/images/markers/marker-we-9.png',
158   - new google.maps.Size(21, 32),
159   - new google.maps.Point(0,0),
160   - new google.maps.Point(16, 35)
161   - );
162   - var image10 = new google.maps.MarkerImage('/images/markers/marker-empl-1.png',
163   - new google.maps.Size(21, 32),
164   - new google.maps.Point(0,0),
165   - new google.maps.Point(16, 35)
166   - );
167   - var image11 = new google.maps.MarkerImage('/images/markers/marker-empl-2.png',
168   - new google.maps.Size(21, 32),
169   - new google.maps.Point(0,0),
170   - new google.maps.Point(16, 35)
171   - );
172   - var image12 = new google.maps.MarkerImage('/images/markers/marker-empl-3.png',
173   - new google.maps.Size(21, 32),
174   - new google.maps.Point(0,0),
175   - new google.maps.Point(16, 35)
176   - );
177   - var image13 = new google.maps.MarkerImage('/images/markers/marker-empl-4.png',
178   - new google.maps.Size(21, 32),
179   - new google.maps.Point(0,0),
180   - new google.maps.Point(16, 35)
181   - );
182   - var image14 = new google.maps.MarkerImage('/images/markers/marker-empl-5.png',
183   - new google.maps.Size(21, 32),
184   - new google.maps.Point(0,0),
185   - new google.maps.Point(16, 35)
186   - );
187   - var image15 = new google.maps.MarkerImage('/images/markers/marker-empl-6.png',
188   - new google.maps.Size(21, 32),
189   - new google.maps.Point(0,0),
190   - new google.maps.Point(16, 35)
191   - );
192   - var image16 = new google.maps.MarkerImage('/images/markers/marker-empl-7.png',
193   - new google.maps.Size(21, 32),
194   - new google.maps.Point(0,0),
195   - new google.maps.Point(16, 35)
196   - );
197   - var image17 = new google.maps.MarkerImage('/images/markers/marker-empl-8.png',
198   - new google.maps.Size(21, 32),
199   - new google.maps.Point(0,0),
200   - new google.maps.Point(16, 35)
201   - );
202   - var image18 = new google.maps.MarkerImage('/images/markers/marker-empl-9.png',
203   - new google.maps.Size(21, 32),
204   - new google.maps.Point(0,0),
205   - new google.maps.Point(16, 35)
206   - );
  99 + </div>
  100 + <div class="section-box-map">
  101 + <div class="shadow-map"></div>
  102 + <div id="map_cloud" style="display: none;">
  103 + <script type="text/javascript">
  104 + function initialize()
  105 + {
  106 + var start_position = new google.maps.LatLng('56', '30');
  107 + var settings = {
  108 + zoom : 7, scrollwheel : false, center : start_position,
  109 + mapTypeControl : false,
  110 + mapTypeControlOptions : {style : google.maps.MapTypeControlStyle.DROPDOWN_MENU},
  111 + navigationControl : false,
  112 + navigationControlOptions : {style : google.maps.NavigationControlStyle.SMALL},
  113 + scaleControl : false, streetViewControl : false, rotateControl : false,
  114 + zoomControl : true, mapTypeId : google.maps.MapTypeId.ROADMAP
  115 + };
  116 + var map = new google.maps.Map(document.getElementById("map_canvas"), settings);
207 117  
208   - var markers = [];
  118 + var image1 = new google.maps.MarkerImage(
  119 + '/images/markers/marker-we-1.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  120 + );
  121 + var image2 = new google.maps.MarkerImage(
  122 + '/images/markers/marker-we-2.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  123 + );
  124 + var image3 = new google.maps.MarkerImage(
  125 + '/images/markers/marker-we-3.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  126 + );
  127 + var image4 = new google.maps.MarkerImage(
  128 + '/images/markers/marker-we-4.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  129 + );
  130 + var image5 = new google.maps.MarkerImage(
  131 + '/images/markers/marker-we-5.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  132 + );
  133 + var image6 = new google.maps.MarkerImage(
  134 + '/images/markers/marker-we-6.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  135 + );
  136 + var image7 = new google.maps.MarkerImage(
  137 + '/images/markers/marker-we-7.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  138 + );
  139 + var image8 = new google.maps.MarkerImage(
  140 + '/images/markers/marker-we-8.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  141 + );
  142 + var image9 = new google.maps.MarkerImage(
  143 + '/images/markers/marker-we-9.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  144 + );
  145 + var image10 = new google.maps.MarkerImage(
  146 + '/images/markers/marker-empl-1.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  147 + );
  148 + var image11 = new google.maps.MarkerImage(
  149 + '/images/markers/marker-empl-2.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  150 + );
  151 + var image12 = new google.maps.MarkerImage(
  152 + '/images/markers/marker-empl-3.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  153 + );
  154 + var image13 = new google.maps.MarkerImage(
  155 + '/images/markers/marker-empl-4.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  156 + );
  157 + var image14 = new google.maps.MarkerImage(
  158 + '/images/markers/marker-empl-5.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  159 + );
  160 + var image15 = new google.maps.MarkerImage(
  161 + '/images/markers/marker-empl-6.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  162 + );
  163 + var image16 = new google.maps.MarkerImage(
  164 + '/images/markers/marker-empl-7.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  165 + );
  166 + var image17 = new google.maps.MarkerImage(
  167 + '/images/markers/marker-empl-8.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  168 + );
  169 + var image18 = new google.maps.MarkerImage(
  170 + '/images/markers/marker-empl-9.png', new google.maps.Size(21, 32), new google.maps.Point(0, 0), new google.maps.Point(16, 35)
  171 + );
209 172  
210   - var marker = new google.maps.Marker({
211   - position: new google.maps.LatLng('56', '35.3'),
212   - map: map,
213   - title: 'Marker Title2',
214   - icon: image1
215   - });
216   - markers.push(marker);
  173 + var markers = [];
217 174  
218   - var marker = new google.maps.Marker({
219   - position: new google.maps.LatLng('56', '36'),
220   - map: map,
221   - title: 'Marker Title2',
222   - icon: image2
223   - });
224   - markers.push(marker);
  175 + var marker = new google.maps.Marker(
  176 + {
  177 + position : new google.maps.LatLng('56', '35.3'), map : map,
  178 + title : 'Marker Title2', icon : image1
  179 + }
  180 + );
  181 + markers.push(marker);
225 182  
226   - var marker = new google.maps.Marker({
227   - position: new google.maps.LatLng('56', '34.5'),
228   - map: map,
229   - title: 'Marker Title3',
230   - icon: image18
231   - });
232   - markers.push(marker);
  183 + var marker = new google.maps.Marker(
  184 + {
  185 + position : new google.maps.LatLng('56', '36'), map : map,
  186 + title : 'Marker Title2', icon : image2
  187 + }
  188 + );
  189 + markers.push(marker);
233 190  
234   - var marker = new google.maps.Marker({
235   - position: new google.maps.LatLng('56', '35'),
236   - map: map,
237   - title: 'Marker Title4',
238   - icon: image13
239   - });
240   - markers.push(marker);
  191 + var marker = new google.maps.Marker(
  192 + {
  193 + position : new google.maps.LatLng('56', '34.5'), map : map,
  194 + title : 'Marker Title3', icon : image18
  195 + }
  196 + );
  197 + markers.push(marker);
241 198  
  199 + var marker = new google.maps.Marker(
  200 + {
  201 + position : new google.maps.LatLng('56', '35'), map : map,
  202 + title : 'Marker Title4', icon : image13
  203 + }
  204 + );
  205 + markers.push(marker);
242 206  
243   - var clusterStyles = [
244   - {
245   - url: '/images/markers/clasters.png',
246   - height: 36,
247   - width: 36
248   - }
  207 + var clusterStyles = [
  208 + {
  209 + url : '/images/markers/clasters.png', height : 36, width : 36
  210 + }
249 211  
250   - ];
251   - markerClusterer = new MarkerClusterer(map, markers,
252   - {
253   - maxZoom: 10,
254   - gridSize: 100,
255   - styles: clusterStyles
256   - });
257   - }
258   - </script>
259   - </div>
260   - <div id="map_canvas" style="width: 100%; height:100%;"></div>
  212 + ];
  213 + markerClusterer = new MarkerClusterer(
  214 + map, markers, {
  215 + maxZoom : 10, gridSize : 100, styles : clusterStyles
  216 + }
  217 + );
  218 + }
  219 + </script>
261 220 </div>
  221 + <div id="map_canvas" style="width: 100%; height:100%;"></div>
262 222 </div>
  223 +</div>
263 224  
264   - <div class="section-box-4">
265   - <div class="box-wr">
266   - <div class="box-all">
267   - <div class="federation-home-title">Зачем нужна Международная федерация проектантов</div>
268   - <div class="federation-home-list-wr">
269   - <ul class="federation-home-list">
270   - <li class="federation-home-list-active"><span>Заказчикам</span></li>
271   - <li><span>Компаниям</span></li>
272   - <li><span>Проектантам</span></li>
273   - <li><span>Наша миссия</span></li>
274   - </ul>
275   - </div>
276   - <div class="federation-home-blocks-wr">
277   - <div class="federation-home-blocks-wr-blocks">
278   - <div class="federation-home-blocks">
279   - <div class="federation-home-ico"><img src="/images/ico-fed-1.png" alt=""/></div>
280   - <div class="federation-home-text">Описания рейтингов</div>
  225 +<div class="section-box-4">
  226 + <div class="box-wr">
  227 + <div class="box-all">
  228 + <div class="federation-home-title">Зачем нужна Международная федерация проектантов</div>
  229 + <div class="federation-home-list-wr">
  230 + <ul class="federation-home-list">
  231 + <li class="federation-home-list-active"><span>Заказчикам</span></li>
  232 + <li><span>Компаниям</span></li>
  233 + <li><span>Проектантам</span></li>
  234 + <li><span>Наша миссия</span></li>
  235 + </ul>
  236 + </div>
  237 + <div class="federation-home-blocks-wr">
  238 + <div class="federation-home-blocks-wr-blocks">
  239 + <div class="federation-home-blocks">
  240 + <div class="federation-home-ico"><img src="/images/ico-fed-1.png" alt=""/>
281 241 </div>
282   - <div class="federation-home-blocks">
283   - <div class="federation-home-ico"><img src="/images/ico-fed-2.png" alt=""/></div>
284   - <div class="federation-home-text">Вы получаете лучшую цену</div>
  242 + <div class="federation-home-text">Описания рейтингов</div>
  243 + </div>
  244 + <div class="federation-home-blocks">
  245 + <div class="federation-home-ico"><img src="/images/ico-fed-2.png" alt=""/>
285 246 </div>
286   - <div class="federation-home-blocks">
287   - <div class="federation-home-ico"><img src="/images/ico-fed-3.png" alt=""/></div>
288   - <div class="federation-home-text">Гарантии получения проекта в срок</div>
  247 + <div class="federation-home-text">Вы получаете лучшую цену</div>
  248 + </div>
  249 + <div class="federation-home-blocks">
  250 + <div class="federation-home-ico"><img src="/images/ico-fed-3.png" alt=""/>
289 251 </div>
  252 + <div class="federation-home-text">Гарантии получения проекта в срок</div>
290 253 </div>
  254 + </div>
291 255  
292   - <div class="federation-home-blocks-wr-blocks">
293   - <div class="federation-home-blocks">
294   - <div class="federation-home-ico"><img src="/images/ico-fed-1.png" alt=""/></div>
295   - <div class="federation-home-text">2Описания рейтингов</div>
  256 + <div class="federation-home-blocks-wr-blocks">
  257 + <div class="federation-home-blocks">
  258 + <div class="federation-home-ico"><img src="/images/ico-fed-1.png" alt=""/>
296 259 </div>
297   - <div class="federation-home-blocks">
298   - <div class="federation-home-ico"><img src="/images/ico-fed-2.png" alt=""/></div>
299   - <div class="federation-home-text">2Вы получаете лучшую цену</div>
  260 + <div class="federation-home-text">2Описания рейтингов</div>
  261 + </div>
  262 + <div class="federation-home-blocks">
  263 + <div class="federation-home-ico"><img src="/images/ico-fed-2.png" alt=""/>
300 264 </div>
301   - <div class="federation-home-blocks">
302   - <div class="federation-home-ico"><img src="/images/ico-fed-3.png" alt=""/></div>
303   - <div class="federation-home-text">2Гарантии получения проекта в срок</div>
  265 + <div class="federation-home-text">2Вы получаете лучшую цену</div>
  266 + </div>
  267 + <div class="federation-home-blocks">
  268 + <div class="federation-home-ico"><img src="/images/ico-fed-3.png" alt=""/>
304 269 </div>
  270 + <div class="federation-home-text">2Гарантии получения проекта в срок</div>
305 271 </div>
  272 + </div>
306 273  
307   - <div class="federation-home-blocks-wr-blocks">
308   - <div class="federation-home-blocks">
309   - <div class="federation-home-ico"><img src="/images/ico-fed-1.png" alt=""/></div>
310   - <div class="federation-home-text">3Описания рейтингов</div>
  274 + <div class="federation-home-blocks-wr-blocks">
  275 + <div class="federation-home-blocks">
  276 + <div class="federation-home-ico"><img src="/images/ico-fed-1.png" alt=""/>
311 277 </div>
312   - <div class="federation-home-blocks">
313   - <div class="federation-home-ico"><img src="/images/ico-fed-2.png" alt=""/></div>
314   - <div class="federation-home-text">3Вы получаете лучшую цену</div>
  278 + <div class="federation-home-text">3Описания рейтингов</div>
  279 + </div>
  280 + <div class="federation-home-blocks">
  281 + <div class="federation-home-ico"><img src="/images/ico-fed-2.png" alt=""/>
315 282 </div>
316   - <div class="federation-home-blocks">
317   - <div class="federation-home-ico"><img src="/images/ico-fed-3.png" alt=""/></div>
318   - <div class="federation-home-text">3Гарантии получения проекта в срок</div>
  283 + <div class="federation-home-text">3Вы получаете лучшую цену</div>
  284 + </div>
  285 + <div class="federation-home-blocks">
  286 + <div class="federation-home-ico"><img src="/images/ico-fed-3.png" alt=""/>
319 287 </div>
  288 + <div class="federation-home-text">3Гарантии получения проекта в срок</div>
320 289 </div>
  290 + </div>
321 291  
322   - <div class="federation-home-blocks-wr-blocks">
323   - <div class="federation-home-blocks">
324   - <div class="federation-home-ico"><img src="/images/ico-fed-1.png" alt=""/></div>
325   - <div class="federation-home-text">4Описания рейтингов</div>
  292 + <div class="federation-home-blocks-wr-blocks">
  293 + <div class="federation-home-blocks">
  294 + <div class="federation-home-ico"><img src="/images/ico-fed-1.png" alt=""/>
326 295 </div>
327   - <div class="federation-home-blocks">
328   - <div class="federation-home-ico"><img src="/images/ico-fed-2.png" alt=""/></div>
329   - <div class="federation-home-text">4Вы получаете лучшую цену</div>
  296 + <div class="federation-home-text">4Описания рейтингов</div>
  297 + </div>
  298 + <div class="federation-home-blocks">
  299 + <div class="federation-home-ico"><img src="/images/ico-fed-2.png" alt=""/>
330 300 </div>
331   - <div class="federation-home-blocks">
332   - <div class="federation-home-ico"><img src="/images/ico-fed-3.png" alt=""/></div>
333   - <div class="federation-home-text">4Гарантии получения проекта в срок</div>
  301 + <div class="federation-home-text">4Вы получаете лучшую цену</div>
  302 + </div>
  303 + <div class="federation-home-blocks">
  304 + <div class="federation-home-ico"><img src="/images/ico-fed-3.png" alt=""/>
334 305 </div>
  306 + <div class="federation-home-text">4Гарантии получения проекта в срок</div>
335 307 </div>
336 308 </div>
337 309 </div>
338 310 </div>
339   - </div>
340 311 \ No newline at end of file
  312 + </div>
  313 +</div>
341 314 \ No newline at end of file
... ...
frontend/views/site/registration.php
... ... @@ -117,7 +117,10 @@
117 117 </div>
118 118 <div class="input-blocks-wrapper">
119 119 <div class="input-blocks">
120   - <?= $form->field($model, 'city', ['enableClientValidation' => false, 'options' => ['class' => 'required-no-star']])
  120 + <?= $form->field($model, 'city', [
  121 + 'enableClientValidation' => false,
  122 + 'options' => [ 'class' => 'required-no-star' ],
  123 + ])
121 124 ->widget(Select2::classname(), [
122 125 'options' => [ 'placeholder' => 'Выбор города ...' ],
123 126 'pluginOptions' => [
... ... @@ -199,9 +202,6 @@
199 202 $('.field-signupform-lastname label').html(labelLastName)
200 203 $('.register-company-block').css('display', 'none');
201 204 $('#w0').yiiActiveForm('remove','signupform-name');
202   -
203   -
204   -
205 205 } else {
206 206 //company
207 207 $('.field-signupform-firstname label').html(labelName+' '+newLabelName)
... ...
frontend/web/css/style.css
... ... @@ -6414,7 +6414,7 @@ input[disabled], select[disabled] {
6414 6414 position: relative;
6415 6415 height: 54px;
6416 6416 }
6417   -.admin-project-file .admin-project-file-btn{
  6417 +.admin-project-file .admin-project-file-btn, .fileloader-file .admin-project-file-btn {
6418 6418 background: #fff;
6419 6419 color: #0072bc;
6420 6420 height: 29px;
... ... @@ -6428,12 +6428,12 @@ input[disabled], select[disabled] {
6428 6428 border-radius: 4px;
6429 6429 cursor: pointer;
6430 6430 }
6431   -.admin-project-file .admin-project-file-btn:hover{
  6431 +.admin-project-file .admin-project-file-btn:hover, .fileloader-file .admin-project-file-btn:hover{
6432 6432 transition: 0.2s;
6433 6433 background: #0072bc;
6434 6434 color: #fff;
6435 6435 }
6436   -.admin-project-file .gen-admin-title{
  6436 +.admin-project-file .gen-admin-title, .fileloader-file .gen-admin-title{
6437 6437 font-size: 13px;
6438 6438 font-weight: 700;
6439 6439 margin-bottom: 10px;
... ... @@ -6444,7 +6444,7 @@ input[disabled], select[disabled] {
6444 6444 cursor: pointer;
6445 6445 margin-top: 8px;
6446 6446 }
6447   -.admin-project-file .not-file-mb-adm{
  6447 +.admin-project-file .not-file-mb-adm, .fileloader-file .not-file-mb-adm {
6448 6448 position: static;
6449 6449 margin-left: 10px;
6450 6450 width: 540px;
... ...