Snippets

Updated by Илья Караваев

File view.js Modified

  • Ignore whitespace
  • Hide word diff
 export default function(modelData = false) {
-	var modelTemplate = _.template(`
-	<div class="model model_status_<%= model.status %>" data-model>
-		<% var costFormId = _.uniqueId('cost-form'); %>
-		<div class="model__inner" data-model-id="<%= model.id %>" data-model-inner>
-			<div class="model__actions">
-				<% if(model.status === 3) { %>
-					<button class="model__actions__item model__actions__item_cost" type="button"  data-modal="#<%= costFormId %>"></button>
-				<% } %>
-				<button class="model__actions__item model__actions__item_edit" type="button" data-edit></button>
-				<button class="model__actions__item model__actions__item_delete" type="button" data-delete></button>
-			</div>
-			<div class="model__date" data-model-date>по <%= app.helpers.formatDate(model.date_to) %></div>
-			<div class="model__info">
-				<div class="model__name"><%= app.helpers.escape(model.name) %></div>
-				<div class="model__contacts">
-					<a href="mailto:<%= model.email %>" class="model__contact link"><%= model.email %></a>
-					<% if (model.phone) { %>
-					<span class="model__contact"><%= model.phone %></span>
-					<% } %>
-				</div>
-				<div class="model__text"><%= app.helpers.multiline(app.helpers.escape(model.description)) %></div>
-				<% if (model.files && model.files.length) { %>
-				<ul class="files">
-					<% _.each(model.files, function(item){ %>
-						<li class="files__item"><a href="<%= app.helpers.escapeUrl(item.url) %>" target="_blank" class="link"><%= app.helpers.escape(item.name) %></a></li>
-					<% }); %>
-				</ul>
-				<% } %>
-			</div>
-			<% if (model.costs && model.costs.length > 0) { %>
-			<div class="costs">
-				<div class="costs__item costs__item_title">
-					<span class="costs__comment">Комментарий</span>
-					<span class="costs__cost">Сумма</span>
-					<span class="costs__commission">Коммисия</span>
-				</div>
-				<ul class="costs__list">
-				<% _.each(model.costs, function(item){ %>
-					<li class="costs__item" data-id="<%= item.id %>">
-						<span class="costs__comment">
-							<%= app.helpers.escape(item.comment) %>
-						</span>
-						<span class="costs__cost">
-							<%= app.helpers.formatNumber(item.cost) %>&nbsp;<span class="rouble">a</span>
-						</span>
-						<span class="costs__commission">
-							<%= app.helpers.formatNumber(item.commission) %>&nbsp;<span class="rouble">a</span>
-						</span>
-						<span class="costs__delete"></span>
-					</li>
-				<% }); %>
-				</ul>
-				<div class="costs__item costs__item_result">
-					<span class="costs__comment">
-						Итого:
-					</span>
-					<span class="costs__cost"><%= app.helpers.formatNumber(_.reduce(model.costs, function(memo, item){ return memo + item.cost; }, 0)) %>&nbsp;<span class="rouble">a</span></span>
-					<span class="costs__commission"><%= app.helpers.formatNumber(_.reduce(model.costs, function(memo, item){ return memo + item.commission; }, 0)) %>&nbsp;<span class="rouble">a</span></span>
-				</div>
-			</div>
-			<% } %>
-			<form class="model__cost-form modal" data-status="<%= model.status %>" action="<%= app.config.urls.costs + model.id %>" id="<%= costFormId %>">
-				<div class="model__cost-form__title title title_level_5">&laquo;<%= app.helpers.escape(model.name) %>&raquo; &mdash; добавить платеж</div>
-				<input class="model__cost-form__field model__cost-form__field_inline field" placeholder="Сумма" name="cost" />
-				<input class="model__cost-form__field model__cost-form__field_inline model__cost-form__field_commission field" placeholder="Комиссия" name="commission" value="20"/>
-				<textarea class="model__cost-form__field field" placeholder="Комментарий" name="comment"></textarea>
-				<button class="model__cost-form__button button" type="submit">Сохранить</button>
-			</form>
-		</div>
-	</div>
-	`);
+    var modelTemplate = _.template(`
+    <div class="model model_status_<%= model.status %>" data-model>
+        <% var costFormId = _.uniqueId('cost-form'); %>
+        <div class="model__inner" data-model-id="<%= model.id %>" data-model-inner>
+            <div class="model__actions">
+                <% if(model.status === 3) { %>
+                    <button class="model__actions__item model__actions__item_cost" type="button"  data-modal="#<%= costFormId %>"></button>
+                <% } %>
+                <button class="model__actions__item model__actions__item_edit" type="button" data-edit></button>
+                <button class="model__actions__item model__actions__item_delete" type="button" data-delete></button>
+            </div>
+            <div class="model__date" data-model-date>по <%= app.helpers.formatDate(model.date_to) %></div>
+            <div class="model__info">
+                <div class="model__name"><%= app.helpers.escape(model.name) %></div>
+                <div class="model__contacts">
+                    <a href="mailto:<%= model.email %>" class="model__contact link"><%= model.email %></a>
+                    <% if (model.phone) { %>
+                    <span class="model__contact"><%= model.phone %></span>
+                    <% } %>
+                </div>
+                <div class="model__text"><%= app.helpers.multiline(app.helpers.escape(model.description)) %></div>
+                <% if (model.files && model.files.length) { %>
+                <ul class="files">
+                    <% _.each(model.files, function(item){ %>
+                        <li class="files__item"><a href="<%= app.helpers.escapeUrl(item.url) %>" target="_blank" class="link"><%= app.helpers.escape(item.name) %></a></li>
+                    <% }); %>
+                </ul>
+                <% } %>
+            </div>
+            <% if (model.costs && model.costs.length > 0) { %>
+            <div class="costs">
+                <div class="costs__item costs__item_title">
+                    <span class="costs__comment">Комментарий</span>
+                    <span class="costs__cost">Сумма</span>
+                    <span class="costs__commission">Коммисия</span>
+                </div>
+                <ul class="costs__list">
+                <% _.each(model.costs, function(item){ %>
+                    <li class="costs__item" data-id="<%= item.id %>">
+                        <span class="costs__comment">
+                            <%= app.helpers.escape(item.comment) %>
+                        </span>
+                        <span class="costs__cost">
+                            <%= app.helpers.formatNumber(item.cost) %>&nbsp;<span class="rouble">a</span>
+                        </span>
+                        <span class="costs__commission">
+                            <%= app.helpers.formatNumber(item.commission) %>&nbsp;<span class="rouble">a</span>
+                        </span>
+                        <span class="costs__delete"></span>
+                    </li>
+                <% }); %>
+                </ul>
+                <div class="costs__item costs__item_result">
+                    <span class="costs__comment">
+                        Итого:
+                    </span>
+                    <span class="costs__cost"><%= app.helpers.formatNumber(_.reduce(model.costs, function(memo, item){ return memo + item.cost; }, 0)) %>&nbsp;<span class="rouble">a</span></span>
+                    <span class="costs__commission"><%= app.helpers.formatNumber(_.reduce(model.costs, function(memo, item){ return memo + item.commission; }, 0)) %>&nbsp;<span class="rouble">a</span></span>
+                </div>
+            </div>
+            <% } %>
+            <form class="model__cost-form modal" data-status="<%= model.status %>" action="<%= app.config.urls.costs + model.id %>" id="<%= costFormId %>">
+                <div class="model__cost-form__title title title_level_5">&laquo;<%= app.helpers.escape(model.name) %>&raquo; &mdash; добавить платеж</div>
+                <input class="model__cost-form__field model__cost-form__field_inline field" placeholder="Сумма" name="cost" />
+                <input class="model__cost-form__field model__cost-form__field_inline model__cost-form__field_commission field" placeholder="Комиссия" name="commission" value="20"/>
+                <textarea class="model__cost-form__field field" placeholder="Комментарий" name="comment"></textarea>
+                <button class="model__cost-form__button button" type="submit">Сохранить</button>
+            </form>
+        </div>
+    </div>
+    `);
 
-	var askForDeleteTemplate = _.template(`
-		<div class="model__delete-block" data-delete-block>
-			<div class="model__name model__name_indent"><%= app.helpers.escape(model.name) %></div>
-			<div class="model__text">Вы уверенны, что хотите удалить?</div>
-			<button class="model__deleted button" type="button" data-deleted>УДАЛИТЬ</button>
-			<button class="model__canceled button" type="button" data-canceled>ОТМЕНА</button>
-		</div>
-	`);
+    var askForDeleteTemplate = _.template(`
+        <div class="model__delete-block" data-delete-block>
+            <div class="model__name model__name_indent"><%= app.helpers.escape(model.name) %></div>
+            <div class="model__text">Вы уверенны, что хотите удалить?</div>
+            <button class="model__deleted button" type="button" data-deleted>УДАЛИТЬ</button>
+            <button class="model__canceled button" type="button" data-canceled>ОТМЕНА</button>
+        </div>
+    `);
 
-	var $wrapper = $(this);
-	var html = modelTemplate({ model: modelData });
-	var $block = $(html).appendTo($wrapper);
-	var $modelInner = $wrapper.find('[data-model-inner]');
-	var modelId = $wrapper.find('[data-model-id]').data('modelId');
-	var $model = $wrapper.find('[data-model]');
+    var $wrapper = $(this);
+    var html = modelTemplate({ model: modelData });
+    var $block = $(html).appendTo($wrapper);
+    var $modelInner = $wrapper.find('[data-model-inner]');
+    var modelId = $wrapper.find('[data-model-id]').data('modelId');
+    var $model = $wrapper.find('[data-model]');
 
-	var initCostForm = function(){
-		var $form = $model.find('.model__cost-form');
-		$form.ajaxForm({
-			type: 'post',
-			beforeSubmit: function(){
-				$form.find('button').attr('disabled', 'disabled');
-			},
-			success: function(data){
-				alertify.success('Данные успешно сохранены');
-				$.arcticmodal('close');
-				$model.html(modelTemplate({ model: data }));
-				modelData = data;
+    var initCostForm = function(){
+        var $form = $model.find('.model__cost-form');
+        $form.ajaxForm({
+            type: 'post',
+            beforeSubmit: function(){
+                $form.find('button').attr('disabled', 'disabled');
+            },
+            success: function(data){
+                alertify.success('Данные успешно сохранены');
+                $.arcticmodal('close');
+                $model.html(modelTemplate({ model: data }));
+                modelData = data;
 
-				initPlugins();
-				initCostForm();
-			},
-			error: function(data){
-				$form.find('button').removeAttr('disabled');
-				alertify.error(data.responseJSON.message);
-			}
-		});
+                initPlugins();
+                initCostForm();
+            },
+            error: function(data){
+                $form.find('button').removeAttr('disabled');
+                alertify.error(data.responseJSON.message);
+            }
+        });
 
-		$model.find(".costs__item");.each( function (el) {
-			var id = $(this).data('id');
-			var $removeButton = $(this).find(".costs__delete");
-			$removeButton.on('click', function () {
-				alertify
-				.okBtn("Удалить")
-				.cancelBtn("Отменить")
-				.confirm("<div class='model__comment-form__title title title_level_5'> Удалить запись?</div>", function() {
-					$.ajax({
-						url: app.config.urls.costs + modelId,
-						data: {cost : id},
-						type: 'DELETE',
-						contentType: 'application/json',
-							dataType: 'json',
-						success: function(data){
-							alertify.success('Данные успешно сохранены');
-							console.log(data);
+        $model.find(".costs__item");.each( function (el) {
+            var id = $(this).data('id');
+            var $removeButton = $(this).find(".costs__delete");
+            $removeButton.on('click', function () {
+                alertify
+                .okBtn("Удалить")
+                .cancelBtn("Отменить")
+                .confirm("<div class='model__comment-form__title title title_level_5'> Удалить запись?</div>", function() {
+                    $.ajax({
+                        url: app.config.urls.costs + modelId,
+                        data: {cost : id},
+                        type: 'DELETE',
+                        contentType: 'application/json',
+                            dataType: 'json',
+                        success: function(data){
+                            alertify.success('Данные успешно сохранены');
+                            console.log(data);
 
-							$model.html(modelTemplate({ model: data }));
-							modelData = data;
+                            $model.html(modelTemplate({ model: data }));
+                            modelData = data;
 
-							initPlugins();
-							initCostForm();
-						},
-						error: function(data){
-							alertify.error(data.responseJSON.message);
-						}
-					});
-				}, function() {
-					alertify.error("Отмена");
-				});
+                            initPlugins();
+                            initCostForm();
+                        },
+                        error: function(data){
+                            alertify.error(data.responseJSON.message);
+                        }
+                    });
+                }, function() {
+                    alertify.error("Отмена");
+                });
 
-			})
-		})
-	};
+            })
+        })
+    };
 
-	var initPlugins = function(){
-		$model.find('[data-modal]').plugin('modal-link');
-		$model.plugins(['field', 'select']);
-	};
+    var initPlugins = function(){
+        $model.find('[data-modal]').plugin('modal-link');
+        $model.plugins(['field', 'select']);
+    };
 
-	initPlugins();
-	initCostForm();
+    initPlugins();
+    initCostForm();
 
-	$wrapper.on('click', '[data-edit]', function () {
-		$model.data('plugins', []);
-		$model.empty().plugin('application', modelData, function(editTender){
-			$model.html(modelTemplate({ model: editTender }));
-			modelData = editTender;
+    $wrapper.on('click', '[data-edit]', function () {
+        $model.data('plugins', []);
+        $model.empty().plugin('application', modelData, function(editTender){
+            $model.html(modelTemplate({ model: editTender }));
+            modelData = editTender;
 
-			initPlugins();
-			initCostForm();
-		});
-	});
+            initPlugins();
+            initCostForm();
+        });
+    });
 
-	$wrapper.on('click', '[data-delete]', function () {
-		$model.html(askForDeleteTemplate({ model: modelData }));
-	});
+    $wrapper.on('click', '[data-delete]', function () {
+        $model.html(askForDeleteTemplate({ model: modelData }));
+    });
 
-	$wrapper.on('click', '[data-deleted]', function () {
-		$.ajax({
-			url: app.config.urls.models + modelId,
-			type: 'DELETE',
-			contentType: 'application/json',
-			dataType: 'json',
-			success: function(data) {
-				$model.remove();
-				alertify.logPosition("bottom right");
-				alertify.error("Запись удалена");
-			},
-			error: function(data){
-				alertify.error(data.responseJSON.message);
-			}
-		});
-	});
+    $wrapper.on('click', '[data-deleted]', function () {
+        $.ajax({
+            url: app.config.urls.models + modelId,
+            type: 'DELETE',
+            contentType: 'application/json',
+            dataType: 'json',
+            success: function(data) {
+                $model.remove();
+                alertify.logPosition("bottom right");
+                alertify.error("Запись удалена");
+            },
+            error: function(data){
+                alertify.error(data.responseJSON.message);
+            }
+        });
+    });
 
-	$wrapper.on('click', '[data-canceled]', function () {
-		$model.html(modelTemplate({ model: modelData }));
-	});
+    $wrapper.on('click', '[data-canceled]', function () {
+        $model.html(modelTemplate({ model: modelData }));
+    });
 }
Updated by Илья Караваев

File ActiveRecord.php Deleted

  • Ignore whitespace
  • Hide word diff
-namespace ...;
-
-use ...;
-
-/**
- * Class ActiveRecord
- *
- * @property integer $id
- * @property string $name
- * @property string $phone
- * @property string $email
- * @property string $description
- * @property string $date_from
- * @property string $date_to
- * @property string $created_at
- * @property string $updated_at
- *
- * @property File[] $files
- */
-class ActiveRecord extends CommonActiveRecord
-{
-    protected $_files = [];
-    protected $_filesForDelete = [];
-    
-    public static function tableName()
-    {
-        return '{{%active_record}}';
-    }
-
-    public function behaviors()
-    {
-        return [
-            [
-                'class' => TimestampBehavior::className(),
-                'value' => new Expression('NOW()'),
-                'attributes' => [
-                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'],
-                    ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at']
-                ],
-            ],
-            [
-                'class' => AttributeBehavior::className(),
-                'attributes' => [
-                    ActiveRecord::EVENT_BEFORE_INSERT => 'date_from',
-                    ActiveRecord::EVENT_BEFORE_UPDATE => 'date_from',
-                    ActiveRecord::EVENT_BEFORE_VALIDATE => 'date_from',
-                ],
-                'value' => function ($event) {
-                    return date('Y-m-d', strtotime($this->date_from));
-                },
-            ],
-            [
-                'class' => AttributeBehavior::className(),
-                'attributes' => [
-                    ActiveRecord::EVENT_BEFORE_INSERT => 'date_to',
-                    ActiveRecord::EVENT_BEFORE_UPDATE => 'date_to',
-                    ActiveRecord::EVENT_BEFORE_VALIDATE => 'date_to',
-                ],
-                'value' => function ($event) {
-                    return date('Y-m-d', strtotime($this->date_to));
-                },
-            ],
-            [
-                'class' => AttributeBehavior::className(),
-                'attributes' => [
-                    ActiveRecord::EVENT_AFTER_FIND => 'name',
-                ],
-                'value' => function ($event) {
-                    return Html::decode($this->name);
-                },
-            ],
-            [
-                'class' => AttributeBehavior::className(),
-                'attributes' => [
-                    ActiveRecord::EVENT_AFTER_FIND => 'description',
-                ],
-                'value' => function ($event) {
-                    return Html::decode($this->description);
-                },
-            ],
-            [
-                'class' => AttributeBehavior::className(),
-                'attributes' => [
-                    ActiveRecord::EVENT_AFTER_FIND => 'comment',
-                ],
-                'value' => function ($event) {
-                    return Html::decode($this->comment);
-                },
-            ],
-            [
-                'class' => AttributeBehavior::className(),
-                'attributes' => [
-                    ActiveRecord::EVENT_BEFORE_INSERT => 'phone',
-                    ActiveRecord::EVENT_BEFORE_UPDATE => 'phone',
-                    ActiveRecord::EVENT_AFTER_FIND    => 'phone',
-                ],
-                'value' => function (\yii\base\Event $event) {
-                    if ($this->phone) {
-                        if ($event->name == ActiveRecord::EVENT_BEFORE_INSERT || $event->name == ActiveRecord::EVENT_BEFORE_UPDATE) {
-                                return preg_replace('/[^0-9]/u', '', $this->phone);
-                        }  else {
-                            return '+7 ' . Helper::formatPhone($this->phone,'');
-                        }
-                    }
-                    return "";
-                },
-            ],
-        ];
-    }
-    
-    public function attributeLabels()
-    {
-        return [
-            'name' => 'Название',
-            'description' => 'Описание',
-            'date_from' => 'Начало срока',
-            'date_to' => 'Конец срока',
-            'email' => 'Email',
-            'phone' => 'Телефон',
-        ];
-    }
-
-
-    public function rules()
-    {
-        retirn [
-            [['name', 'description', 'date_from', 'date_to', 'email'], 'required'],
-            [['description'], 'string'],
-            [['max_price'], 'integer'],
-            [['max_price'], 'number', 'min' => 0, 'max' => 2147483647],
-            [['date_from', 'date_to', 'created_at', 'updated_at'], 'safe'],
-            [['date_from', 'date_to'], 'date', 'format' => 'php:Y-m-d'],
-            [['name'], 'string', 'max' => 64],
-            [['email'], 'string', 'max' => 255],
-            [['email'], 'email'],
-            [['phone'], 'string', 'max' => 20],
-            [['phone'], function ($attribute, $params) {
-                if ($this->$attribute) {
-                    $clearPhone = preg_replace('/[^0-9]/u', '', $this->$attribute);
-                    if (mb_strlen($clearPhone, 'UTF-8') != 11) {
-                        $this->addError($attribute, '...');
-                    }
-                }
-            }],
-            [['name', 'description', 'email', 'phone'], 'filter', 'filter' => '\yii\helpers\HtmlPurifier::process'],
-            [['name', 'description', 'email', 'phone'], 'filter', 'filter' => '\yii\helpers\Html::encode'],
-            [
-                ['name'],
-                'unique',
-                'targetAttribute' => [
-                    'name',
-                    'description',
-                    'email',
-                    'date_from',
-                    'date_to'
-                ],
-                'message' => '...',
-                'when' => function () {
-                    return $this->isNewRecord;
-                }
-            ],
-            'date_to', function ($attribute, $params) {
-                if (strtotime($this->$attribute) < strtotime($this->date_from)) {
-                    $this->addError('date_to', '...');
-                }
-            }];
-        ];
-    }
-    
-    public function getFiles()
-    {
-        return $this
-            ->hasMany(File::className(), ['id' => 'file_id'])
-            ->viaTable('doc', ['doc_id' => 'id']);
-    }
-
-    public function setFilesForDelete($files)
-    {
-        if ($files) {
-            $this->_filesForDelete = is_array($files) ? $files : explode(',', preg_replace('/([\d,]+)[,]&?/', '$1', $files));
-        } else {
-            $this->_filesForDelete = [];
-        }
-    }
-
-    public function afterSave($insert, $changedAttributes)
-    {
-        \Yii::$app
-            ->db
-            ->createCommand()
-            ->delete('doc', 'id = ' . $this->id)
-            ->execute();
-
-        if (!empty($this->_files)) {
-            foreach ($this->_files as $file) {
-                \Yii::$app
-                    ->db
-                    ->createCommand()
-                    ->insert('doc', [
-                        'id' => $this->id,
-                        'file_id' => $file,
-                        'attached_at' => new Expression('NOW()'),
-                    ])->execute();
-            }
-        }
-
-        if (!empty($this->_filesForDelete)) {
-            foreach ($this->_filesForDelete as $fileId) {
-                File::findOne($fileId)->delete();
-            }
-        }
-        parent::afterSave($insert, $changedAttributes);
-    }
-
-    public function setFiles($files)
-    {
-        if ($files) {
-            $this->_files = is_array($files) ? $files : explode(',', $files);
-        } else {
-            $this->_files = [];
-        }
-    }
-
-    public function beforeDelete()
-    {
-        if ($this->files) {
-            foreach ($this->files as $file) {
-                if ($file->delete() === false) {
-                    return false;
-                }
-            }
-        }
-        return parent::beforeDelete();
-    }
-
-    public static function find()
-    {
-        return \Yii::createObject(ActiceQuery::className(), [get_called_class()]);
-    }
-
-    public function hasLimitEditing()
-    {
-        $limitEditing = \Yii::$app->formatter->asTimestamp($this->created_at) + \Yii::$app->params['editingLimit'];
-        
-        if (time() >= $limitEditing) {
-            return true;
-        }
-        
-        return false;
-    }
-}

File Model.php Added

  • Ignore whitespace
  • Hide word diff
+namespace ...;
+
+use ...;
+
+/**
+ * Class ActiveRecord
+ *
+ * @property integer $id
+ * @property string $name
+ * @property string $phone
+ * @property string $email
+ * @property string $description
+ * @property string $date_from
+ * @property string $date_to
+ * @property string $created_at
+ * @property string $updated_at
+ *
+ * @property File[] $files
+ */
+class ActiveRecord extends CommonActiveRecord
+{
+    protected $_files = [];
+    protected $_filesForDelete = [];
+    
+    public static function tableName()
+    {
+        return '{{%active_record}}';
+    }
+
+    public function behaviors()
+    {
+        return [
+            [
+                'class' => TimestampBehavior::className(),
+                'value' => new Expression('NOW()'),
+                'attributes' => [
+                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'],
+                    ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at']
+                ],
+            ],
+            [
+                'class' => AttributeBehavior::className(),
+                'attributes' => [
+                    ActiveRecord::EVENT_BEFORE_INSERT => 'date_from',
+                    ActiveRecord::EVENT_BEFORE_UPDATE => 'date_from',
+                    ActiveRecord::EVENT_BEFORE_VALIDATE => 'date_from',
+                ],
+                'value' => function ($event) {
+                    return date('Y-m-d', strtotime($this->date_from));
+                },
+            ],
+            [
+                'class' => AttributeBehavior::className(),
+                'attributes' => [
+                    ActiveRecord::EVENT_BEFORE_INSERT => 'date_to',
+                    ActiveRecord::EVENT_BEFORE_UPDATE => 'date_to',
+                    ActiveRecord::EVENT_BEFORE_VALIDATE => 'date_to',
+                ],
+                'value' => function ($event) {
+                    return date('Y-m-d', strtotime($this->date_to));
+                },
+            ],
+            [
+                'class' => AttributeBehavior::className(),
+                'attributes' => [
+                    ActiveRecord::EVENT_AFTER_FIND => 'name',
+                ],
+                'value' => function ($event) {
+                    return Html::decode($this->name);
+                },
+            ],
+            [
+                'class' => AttributeBehavior::className(),
+                'attributes' => [
+                    ActiveRecord::EVENT_AFTER_FIND => 'description',
+                ],
+                'value' => function ($event) {
+                    return Html::decode($this->description);
+                },
+            ],
+            [
+                'class' => AttributeBehavior::className(),
+                'attributes' => [
+                    ActiveRecord::EVENT_AFTER_FIND => 'comment',
+                ],
+                'value' => function ($event) {
+                    return Html::decode($this->comment);
+                },
+            ],
+            [
+                'class' => AttributeBehavior::className(),
+                'attributes' => [
+                    ActiveRecord::EVENT_BEFORE_INSERT => 'phone',
+                    ActiveRecord::EVENT_BEFORE_UPDATE => 'phone',
+                    ActiveRecord::EVENT_AFTER_FIND    => 'phone',
+                ],
+                'value' => function (\yii\base\Event $event) {
+                    if ($this->phone) {
+                        if ($event->name == ActiveRecord::EVENT_BEFORE_INSERT || $event->name == ActiveRecord::EVENT_BEFORE_UPDATE) {
+                                return preg_replace('/[^0-9]/u', '', $this->phone);
+                        }  else {
+                            return '+7 ' . Helper::formatPhone($this->phone,'');
+                        }
+                    }
+                    return "";
+                },
+            ],
+        ];
+    }
+    
+    public function attributeLabels()
+    {
+        return [
+            'name' => 'Название',
+            'description' => 'Описание',
+            'date_from' => 'Начало срока',
+            'date_to' => 'Конец срока',
+            'email' => 'Email',
+            'phone' => 'Телефон',
+        ];
+    }
+
+
+    public function rules()
+    {
+        retirn [
+            [['name', 'description', 'date_from', 'date_to', 'email'], 'required'],
+            [['description'], 'string'],
+            [['max_price'], 'integer'],
+            [['max_price'], 'number', 'min' => 0, 'max' => 2147483647],
+            [['date_from', 'date_to', 'created_at', 'updated_at'], 'safe'],
+            [['date_from', 'date_to'], 'date', 'format' => 'php:Y-m-d'],
+            [['name'], 'string', 'max' => 64],
+            [['email'], 'string', 'max' => 255],
+            [['email'], 'email'],
+            [['phone'], 'string', 'max' => 20],
+            [['phone'], function ($attribute, $params) {
+                if ($this->$attribute) {
+                    $clearPhone = preg_replace('/[^0-9]/u', '', $this->$attribute);
+                    if (mb_strlen($clearPhone, 'UTF-8') != 11) {
+                        $this->addError($attribute, '...');
+                    }
+                }
+            }],
+            [['name', 'description', 'email', 'phone'], 'filter', 'filter' => '\yii\helpers\HtmlPurifier::process'],
+            [['name', 'description', 'email', 'phone'], 'filter', 'filter' => '\yii\helpers\Html::encode'],
+            [
+                ['name'],
+                'unique',
+                'targetAttribute' => [
+                    'name',
+                    'description',
+                    'email',
+                    'date_from',
+                    'date_to'
+                ],
+                'message' => '...',
+                'when' => function () {
+                    return $this->isNewRecord;
+                }
+            ],
+            'date_to', function ($attribute, $params) {
+                if (strtotime($this->$attribute) < strtotime($this->date_from)) {
+                    $this->addError('date_to', '...');
+                }
+            }];
+        ];
+    }
+    
+    public function getFiles()
+    {
+        return $this
+            ->hasMany(File::className(), ['id' => 'file_id'])
+            ->viaTable('doc', ['doc_id' => 'id']);
+    }
+
+    public function setFilesForDelete($files)
+    {
+        if ($files) {
+            $this->_filesForDelete = is_array($files) ? $files : explode(',', preg_replace('/([\d,]+)[,]&?/', '$1', $files));
+        } else {
+            $this->_filesForDelete = [];
+        }
+    }
+
+    public function afterSave($insert, $changedAttributes)
+    {
+        \Yii::$app
+            ->db
+            ->createCommand()
+            ->delete('doc', 'id = ' . $this->id)
+            ->execute();
+
+        if (!empty($this->_files)) {
+            foreach ($this->_files as $file) {
+                \Yii::$app
+                    ->db
+                    ->createCommand()
+                    ->insert('doc', [
+                        'id' => $this->id,
+                        'file_id' => $file,
+                        'attached_at' => new Expression('NOW()'),
+                    ])->execute();
+            }
+        }
+
+        if (!empty($this->_filesForDelete)) {
+            foreach ($this->_filesForDelete as $fileId) {
+                File::findOne($fileId)->delete();
+            }
+        }
+        parent::afterSave($insert, $changedAttributes);
+    }
+
+    public function setFiles($files)
+    {
+        if ($files) {
+            $this->_files = is_array($files) ? $files : explode(',', $files);
+        } else {
+            $this->_files = [];
+        }
+    }
+
+    public function beforeDelete()
+    {
+        if ($this->files) {
+            foreach ($this->files as $file) {
+                if ($file->delete() === false) {
+                    return false;
+                }
+            }
+        }
+        return parent::beforeDelete();
+    }
+
+    public static function find()
+    {
+        return \Yii::createObject(ActiceQuery::className(), [get_called_class()]);
+    }
+
+    public function hasLimitEditing()
+    {
+        $limitEditing = \Yii::$app->formatter->asTimestamp($this->created_at) + \Yii::$app->params['editingLimit'];
+        
+        if (time() >= $limitEditing) {
+            return true;
+        }
+        
+        return false;
+    }
+}

File view.js Added

  • Ignore whitespace
  • Hide word diff
+export default function(modelData = false) {
+	var modelTemplate = _.template(`
+	<div class="model model_status_<%= model.status %>" data-model>
+		<% var costFormId = _.uniqueId('cost-form'); %>
+		<div class="model__inner" data-model-id="<%= model.id %>" data-model-inner>
+			<div class="model__actions">
+				<% if(model.status === 3) { %>
+					<button class="model__actions__item model__actions__item_cost" type="button"  data-modal="#<%= costFormId %>"></button>
+				<% } %>
+				<button class="model__actions__item model__actions__item_edit" type="button" data-edit></button>
+				<button class="model__actions__item model__actions__item_delete" type="button" data-delete></button>
+			</div>
+			<div class="model__date" data-model-date>по <%= app.helpers.formatDate(model.date_to) %></div>
+			<div class="model__info">
+				<div class="model__name"><%= app.helpers.escape(model.name) %></div>
+				<div class="model__contacts">
+					<a href="mailto:<%= model.email %>" class="model__contact link"><%= model.email %></a>
+					<% if (model.phone) { %>
+					<span class="model__contact"><%= model.phone %></span>
+					<% } %>
+				</div>
+				<div class="model__text"><%= app.helpers.multiline(app.helpers.escape(model.description)) %></div>
+				<% if (model.files && model.files.length) { %>
+				<ul class="files">
+					<% _.each(model.files, function(item){ %>
+						<li class="files__item"><a href="<%= app.helpers.escapeUrl(item.url) %>" target="_blank" class="link"><%= app.helpers.escape(item.name) %></a></li>
+					<% }); %>
+				</ul>
+				<% } %>
+			</div>
+			<% if (model.costs && model.costs.length > 0) { %>
+			<div class="costs">
+				<div class="costs__item costs__item_title">
+					<span class="costs__comment">Комментарий</span>
+					<span class="costs__cost">Сумма</span>
+					<span class="costs__commission">Коммисия</span>
+				</div>
+				<ul class="costs__list">
+				<% _.each(model.costs, function(item){ %>
+					<li class="costs__item" data-id="<%= item.id %>">
+						<span class="costs__comment">
+							<%= app.helpers.escape(item.comment) %>
+						</span>
+						<span class="costs__cost">
+							<%= app.helpers.formatNumber(item.cost) %>&nbsp;<span class="rouble">a</span>
+						</span>
+						<span class="costs__commission">
+							<%= app.helpers.formatNumber(item.commission) %>&nbsp;<span class="rouble">a</span>
+						</span>
+						<span class="costs__delete"></span>
+					</li>
+				<% }); %>
+				</ul>
+				<div class="costs__item costs__item_result">
+					<span class="costs__comment">
+						Итого:
+					</span>
+					<span class="costs__cost"><%= app.helpers.formatNumber(_.reduce(model.costs, function(memo, item){ return memo + item.cost; }, 0)) %>&nbsp;<span class="rouble">a</span></span>
+					<span class="costs__commission"><%= app.helpers.formatNumber(_.reduce(model.costs, function(memo, item){ return memo + item.commission; }, 0)) %>&nbsp;<span class="rouble">a</span></span>
+				</div>
+			</div>
+			<% } %>
+			<form class="model__cost-form modal" data-status="<%= model.status %>" action="<%= app.config.urls.costs + model.id %>" id="<%= costFormId %>">
+				<div class="model__cost-form__title title title_level_5">&laquo;<%= app.helpers.escape(model.name) %>&raquo; &mdash; добавить платеж</div>
+				<input class="model__cost-form__field model__cost-form__field_inline field" placeholder="Сумма" name="cost" />
+				<input class="model__cost-form__field model__cost-form__field_inline model__cost-form__field_commission field" placeholder="Комиссия" name="commission" value="20"/>
+				<textarea class="model__cost-form__field field" placeholder="Комментарий" name="comment"></textarea>
+				<button class="model__cost-form__button button" type="submit">Сохранить</button>
+			</form>
+		</div>
+	</div>
+	`);
+
+	var askForDeleteTemplate = _.template(`
+		<div class="model__delete-block" data-delete-block>
+			<div class="model__name model__name_indent"><%= app.helpers.escape(model.name) %></div>
+			<div class="model__text">Вы уверенны, что хотите удалить?</div>
+			<button class="model__deleted button" type="button" data-deleted>УДАЛИТЬ</button>
+			<button class="model__canceled button" type="button" data-canceled>ОТМЕНА</button>
+		</div>
+	`);
+
+	var $wrapper = $(this);
+	var html = modelTemplate({ model: modelData });
+	var $block = $(html).appendTo($wrapper);
+	var $modelInner = $wrapper.find('[data-model-inner]');
+	var modelId = $wrapper.find('[data-model-id]').data('modelId');
+	var $model = $wrapper.find('[data-model]');
+
+	var initCostForm = function(){
+		var $form = $model.find('.model__cost-form');
+		$form.ajaxForm({
+			type: 'post',
+			beforeSubmit: function(){
+				$form.find('button').attr('disabled', 'disabled');
+			},
+			success: function(data){
+				alertify.success('Данные успешно сохранены');
+				$.arcticmodal('close');
+				$model.html(modelTemplate({ model: data }));
+				modelData = data;
+
+				initPlugins();
+				initCostForm();
+			},
+			error: function(data){
+				$form.find('button').removeAttr('disabled');
+				alertify.error(data.responseJSON.message);
+			}
+		});
+
+		$model.find(".costs__item");.each( function (el) {
+			var id = $(this).data('id');
+			var $removeButton = $(this).find(".costs__delete");
+			$removeButton.on('click', function () {
+				alertify
+				.okBtn("Удалить")
+				.cancelBtn("Отменить")
+				.confirm("<div class='model__comment-form__title title title_level_5'> Удалить запись?</div>", function() {
+					$.ajax({
+						url: app.config.urls.costs + modelId,
+						data: {cost : id},
+						type: 'DELETE',
+						contentType: 'application/json',
+							dataType: 'json',
+						success: function(data){
+							alertify.success('Данные успешно сохранены');
+							console.log(data);
+
+							$model.html(modelTemplate({ model: data }));
+							modelData = data;
+
+							initPlugins();
+							initCostForm();
+						},
+						error: function(data){
+							alertify.error(data.responseJSON.message);
+						}
+					});
+				}, function() {
+					alertify.error("Отмена");
+				});
+
+			})
+		})
+	};
+
+	var initPlugins = function(){
+		$model.find('[data-modal]').plugin('modal-link');
+		$model.plugins(['field', 'select']);
+	};
+
+	initPlugins();
+	initCostForm();
+
+	$wrapper.on('click', '[data-edit]', function () {
+		$model.data('plugins', []);
+		$model.empty().plugin('application', modelData, function(editTender){
+			$model.html(modelTemplate({ model: editTender }));
+			modelData = editTender;
+
+			initPlugins();
+			initCostForm();
+		});
+	});
+
+	$wrapper.on('click', '[data-delete]', function () {
+		$model.html(askForDeleteTemplate({ model: modelData }));
+	});
+
+	$wrapper.on('click', '[data-deleted]', function () {
+		$.ajax({
+			url: app.config.urls.models + modelId,
+			type: 'DELETE',
+			contentType: 'application/json',
+			dataType: 'json',
+			success: function(data) {
+				$model.remove();
+				alertify.logPosition("bottom right");
+				alertify.error("Запись удалена");
+			},
+			error: function(data){
+				alertify.error(data.responseJSON.message);
+			}
+		});
+	});
+
+	$wrapper.on('click', '[data-canceled]', function () {
+		$model.html(modelTemplate({ model: modelData }));
+	});
+}
Created by Илья Караваев

File ActiveRecord.php Added

  • Ignore whitespace
  • Hide word diff
+namespace ...;
+
+use ...;
+
+/**
+ * Class ActiveRecord
+ *
+ * @property integer $id
+ * @property string $name
+ * @property string $phone
+ * @property string $email
+ * @property string $description
+ * @property string $date_from
+ * @property string $date_to
+ * @property string $created_at
+ * @property string $updated_at
+ *
+ * @property File[] $files
+ */
+class ActiveRecord extends CommonActiveRecord
+{
+    protected $_files = [];
+    protected $_filesForDelete = [];
+    
+    public static function tableName()
+    {
+        return '{{%active_record}}';
+    }
+
+    public function behaviors()
+    {
+        return [
+            [
+                'class' => TimestampBehavior::className(),
+                'value' => new Expression('NOW()'),
+                'attributes' => [
+                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'],
+                    ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at']
+                ],
+            ],
+            [
+                'class' => AttributeBehavior::className(),
+                'attributes' => [
+                    ActiveRecord::EVENT_BEFORE_INSERT => 'date_from',
+                    ActiveRecord::EVENT_BEFORE_UPDATE => 'date_from',
+                    ActiveRecord::EVENT_BEFORE_VALIDATE => 'date_from',
+                ],
+                'value' => function ($event) {
+                    return date('Y-m-d', strtotime($this->date_from));
+                },
+            ],
+            [
+                'class' => AttributeBehavior::className(),
+                'attributes' => [
+                    ActiveRecord::EVENT_BEFORE_INSERT => 'date_to',
+                    ActiveRecord::EVENT_BEFORE_UPDATE => 'date_to',
+                    ActiveRecord::EVENT_BEFORE_VALIDATE => 'date_to',
+                ],
+                'value' => function ($event) {
+                    return date('Y-m-d', strtotime($this->date_to));
+                },
+            ],
+            [
+                'class' => AttributeBehavior::className(),
+                'attributes' => [
+                    ActiveRecord::EVENT_AFTER_FIND => 'name',
+                ],
+                'value' => function ($event) {
+                    return Html::decode($this->name);
+                },
+            ],
+            [
+                'class' => AttributeBehavior::className(),
+                'attributes' => [
+                    ActiveRecord::EVENT_AFTER_FIND => 'description',
+                ],
+                'value' => function ($event) {
+                    return Html::decode($this->description);
+                },
+            ],
+            [
+                'class' => AttributeBehavior::className(),
+                'attributes' => [
+                    ActiveRecord::EVENT_AFTER_FIND => 'comment',
+                ],
+                'value' => function ($event) {
+                    return Html::decode($this->comment);
+                },
+            ],
+            [
+                'class' => AttributeBehavior::className(),
+                'attributes' => [
+                    ActiveRecord::EVENT_BEFORE_INSERT => 'phone',
+                    ActiveRecord::EVENT_BEFORE_UPDATE => 'phone',
+                    ActiveRecord::EVENT_AFTER_FIND    => 'phone',
+                ],
+                'value' => function (\yii\base\Event $event) {
+                    if ($this->phone) {
+                        if ($event->name == ActiveRecord::EVENT_BEFORE_INSERT || $event->name == ActiveRecord::EVENT_BEFORE_UPDATE) {
+                                return preg_replace('/[^0-9]/u', '', $this->phone);
+                        }  else {
+                            return '+7 ' . Helper::formatPhone($this->phone,'');
+                        }
+                    }
+                    return "";
+                },
+            ],
+        ];
+    }
+    
+    public function attributeLabels()
+    {
+        return [
+            'name' => 'Название',
+            'description' => 'Описание',
+            'date_from' => 'Начало срока',
+            'date_to' => 'Конец срока',
+            'email' => 'Email',
+            'phone' => 'Телефон',
+        ];
+    }
+
+
+    public function rules()
+    {
+        retirn [
+            [['name', 'description', 'date_from', 'date_to', 'email'], 'required'],
+            [['description'], 'string'],
+            [['max_price'], 'integer'],
+            [['max_price'], 'number', 'min' => 0, 'max' => 2147483647],
+            [['date_from', 'date_to', 'created_at', 'updated_at'], 'safe'],
+            [['date_from', 'date_to'], 'date', 'format' => 'php:Y-m-d'],
+            [['name'], 'string', 'max' => 64],
+            [['email'], 'string', 'max' => 255],
+            [['email'], 'email'],
+            [['phone'], 'string', 'max' => 20],
+            [['phone'], function ($attribute, $params) {
+                if ($this->$attribute) {
+                    $clearPhone = preg_replace('/[^0-9]/u', '', $this->$attribute);
+                    if (mb_strlen($clearPhone, 'UTF-8') != 11) {
+                        $this->addError($attribute, '...');
+                    }
+                }
+            }],
+            [['name', 'description', 'email', 'phone'], 'filter', 'filter' => '\yii\helpers\HtmlPurifier::process'],
+            [['name', 'description', 'email', 'phone'], 'filter', 'filter' => '\yii\helpers\Html::encode'],
+            [
+                ['name'],
+                'unique',
+                'targetAttribute' => [
+                    'name',
+                    'description',
+                    'email',
+                    'date_from',
+                    'date_to'
+                ],
+                'message' => '...',
+                'when' => function () {
+                    return $this->isNewRecord;
+                }
+            ],
+            'date_to', function ($attribute, $params) {
+                if (strtotime($this->$attribute) < strtotime($this->date_from)) {
+                    $this->addError('date_to', '...');
+                }
+            }];
+        ];
+    }
+    
+    public function getFiles()
+    {
+        return $this
+            ->hasMany(File::className(), ['id' => 'file_id'])
+            ->viaTable('doc', ['doc_id' => 'id']);
+    }
+
+    public function setFilesForDelete($files)
+    {
+        if ($files) {
+            $this->_filesForDelete = is_array($files) ? $files : explode(',', preg_replace('/([\d,]+)[,]&?/', '$1', $files));
+        } else {
+            $this->_filesForDelete = [];
+        }
+    }
+
+    public function afterSave($insert, $changedAttributes)
+    {
+        \Yii::$app
+            ->db
+            ->createCommand()
+            ->delete('doc', 'id = ' . $this->id)
+            ->execute();
+
+        if (!empty($this->_files)) {
+            foreach ($this->_files as $file) {
+                \Yii::$app
+                    ->db
+                    ->createCommand()
+                    ->insert('doc', [
+                        'id' => $this->id,
+                        'file_id' => $file,
+                        'attached_at' => new Expression('NOW()'),
+                    ])->execute();
+            }
+        }
+
+        if (!empty($this->_filesForDelete)) {
+            foreach ($this->_filesForDelete as $fileId) {
+                File::findOne($fileId)->delete();
+            }
+        }
+        parent::afterSave($insert, $changedAttributes);
+    }
+
+    public function setFiles($files)
+    {
+        if ($files) {
+            $this->_files = is_array($files) ? $files : explode(',', $files);
+        } else {
+            $this->_files = [];
+        }
+    }
+
+    public function beforeDelete()
+    {
+        if ($this->files) {
+            foreach ($this->files as $file) {
+                if ($file->delete() === false) {
+                    return false;
+                }
+            }
+        }
+        return parent::beforeDelete();
+    }
+
+    public static function find()
+    {
+        return \Yii::createObject(ActiceQuery::className(), [get_called_class()]);
+    }
+
+    public function hasLimitEditing()
+    {
+        $limitEditing = \Yii::$app->formatter->asTimestamp($this->created_at) + \Yii::$app->params['editingLimit'];
+        
+        if (time() >= $limitEditing) {
+            return true;
+        }
+        
+        return false;
+    }
+}

File Controller.php Added

  • Ignore whitespace
  • Hide word diff
+namespace ...;
+
+use ...;
+
+class Controller extends \yii\web\Controller
+{
+    public function behaviors()
+    {
+        $behaviours = [
+            'access' => [
+                'class' => AccessControl::className(),
+                'rules' => [
+                    [
+                        'actions' => [
+                            'index',
+                            'list',
+                            'create',
+                            'update',
+                            'delete',
+                            'upload',
+                            'comment'
+                        ],
+                        'allow' => true,
+                        'roles' => ['@'],
+                    ],
+                ],
+            ],
+            [
+                'class' => 'yii\filters\ContentNegotiator',
+                'only' => [
+                    'list',
+                    'create',
+                    'update',
+                    'delete',
+                    'upload',
+                    'comment'
+                ],
+                'formats' => [
+                    'application/json' => Response::FORMAT_JSON,
+                ],
+            ]
+        ];
+        return ArrayHelper::merge(parent::behaviors(), $behaviours);
+    }
+
+    public function actionIndex()
+    {
+        return $this->render('index');
+    }
+
+    public function actionCreate()
+    {
+        $request = \Yii::$app->request;
+
+        $model = new ActiveRecord();
+        $model->files = $request->post('files');
+        $model->filesForDelete = $request->post('files_delete');
+
+        if ($model->load(Common::prepareRequestData($model->formName())) && $model->save() && $model->refresh()) {
+            return ArrayHelper::toArray($model, [
+                ActiveRecord::className() => [
+                    'id',
+                    'name',
+                    'email',
+                    'phone',
+                    'description',
+                    'comment',
+                    'date_from',
+                    'date_to',
+                    'files',
+                ],
+                File::className() => [
+                    'id',
+                    'name',
+                    'url'
+                ]
+            ]);
+        }
+
+        throw new BadRequestHttpException();
+    }
+
+    public function actionUpdate($id)
+    {
+        $model = ActiveRecord::findOne($id);
+
+        if ($model->hasLimitEditing()) {
+            throw new BadRequestHttpException();
+        }
+
+        $request = \Yii::$app->request;
+
+        $model->files = $request->post('files');
+        $model->filesForDelete = $request->post('files_delete');
+
+        if ($model->load(Common::prepareRequestData($model->formName())) && $model->save() && $model->refresh()) {
+
+            return ArrayHelper::toArray($model, [
+                ActiveRecord::className() => [
+                    'id',
+                    'name',
+                    'email',
+                    'phone',
+                    'description',
+                    'comment',
+                    'date_from',
+                    'date_to',
+                    'files'
+                ],
+                File::className() => [
+                    'id',
+                    'name',
+                    'url'
+                ],
+            ]);
+        }
+
+        throw new BadRequestHttpException();
+    }
+
+    public function actionDelete($id)
+    {
+        ...
+    }
+
+    public function actionComment()
+    {
+        ...
+    }
+
+    public function actionUpload()
+    {
+        ...
+    }
+
+    public function actionAdd()
+    {
+        ...
+    }
+
+    public function actionMove()
+    {
+        ...
+    }
+    
+    ...
+}
HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.