Я пишу приложение - backend: Yii2, frontend : angular. Я использую Yii ActiveController. У меня уже реализована часть приложения, которая отвечает за выборку записей из базы данных и вывод. Теперь я задался вопросом редактирования данных и мне необходимо реализовать update записи. Это я делаю put запросом - но у меня возникла проблема - вижу в консоли отправляются мои данные - но мне приходит ответ - json - с первоначальными (неизменными) данными - хотя ответ от сервера 200 - я вижу в консоли следующую ошибку, мне пишет, что какой-то из атрибутов не является безопасным:
yii\base\Model::onUnsafeAttribute Failed to set unsafe attribute '{"id":"f61e8b51-d16c-464d-9929-44d1b05dba10","lastname":"1Надь","name":"Виктор","fathername":"Сергеевич","location":5,"current_status":3,"company":"BADOO","position":"Middle_JS_Dev_Inc","salary":700,"date_birth":"2019-12-25","date_created":"2019-12-25_13:03:14","photo":null,"wish":null,"documents":null,"notes":null}' in 'app\crm\entities\candidate\Candidate'.
Моя entity Candidates(кандидаты):
<?php
/**
* Created by PhpStorm.
* User: Rox
* Date: 28.03.2019
* Time: 15:31
*/
namespace app\crm\entities\candidate;
use common\models\File;
use app\crm\entities\_traits\InstantiateTrait;
use app\crm\entities\_traits\LazyLoadTrait;
use app\crm\entities\candidate\related\Skills;
use app\crm\entities\City;
use app\crm\entities\Contact;
use app\crm\interfaces\IARCandidate;
use app\crm\interfaces\ICandidate;
use app\crm\interfaces\IEntity;
use app\crm\interfaces\ISkillEntity;
use lhs\Yii2SaveRelationsBehavior\SaveRelationsBehavior;
use ProxyManager\Proxy\LazyLoadingInterface;
use yii\db\ActiveQuery;
use yii\db\ActiveRecord;
use yii\helpers\Json;
/***
* Class Candidate
* @package app\crm\entities\candidate
*
* @property ContactCandidate[] $relatedContacts
* @property SkillCandidate[] $relatedSkills
* @property DocumentCandidate[] $relatedDocuments
* @property City $city
*/
class Candidate extends ActiveRecord implements IEntity, ICandidate, IARCandidate, ISkillEntity
{
use LazyLoadTrait;
/***@var $id CandidateId***/
private $id;
/***@var $name Name***/
private $name;
/***@var $createDate \DateTimeImmutable***/
private $createDate;
/***@var $birthDate \DateTimeImmutable***/
private $birthDate;
private $current_status;
private $info;
private $notes;
private $documents;
/***@var Contacts***/
private $contacts;
/***@var Skills***/
private $skills;
private $stages;
private $photo;
public static function create(CandidateId $id, Name $name, Info $info, string $photo,string $notes, int $location_id = null, array $contacts=[], array $skills=[], array $documents = []): self
{
$candidate = new static();
$candidate->id = $id;
$candidate->name = $name;
$candidate->createDate = new \DateTimeImmutable();
$candidate->current_status = Status::CREATED;
$candidate->info = $info;
$candidate->contacts = new Contacts($contacts);
$candidate->skills = new Skills($skills);
$candidate->location = $location_id;
$candidate->photo = $photo;
$candidate->notes = $notes;
$candidate->documents = new Documents($documents);
return $candidate;
}
public function rename(Name $name): void
{
$this->name = $name;
//$this->recordEvent(new Events\CandidateRenamed($this->id, $name));
}
public function remove(): void
{
if(false){
throw new \DomainException('Some reason why can not delete candidate');
}
//$this->recordEvent(new Events\CandidateRemoved($this->id));
}
public function getId(): CandidateId
{
return $this->id;
}
public function getName(): Name
{
return $this->name;
}
public function getCurrentStatus(): int
{
return $this->current_status;
}
public function getCreateDate(): \DateTimeImmutable
{
return $this->createDate;
}
public function getBirthDate(): \DateTimeImmutable
{
return $this->info->getBirth();
}
public function getInfo(): Info
{
return $this->info;
}
public function setInfo(Info $info):void
{
$this->info = $info;
}
public function setLocation($location)
{
$this->location = $location;
}
public function getPhoto()
{
return $this->photo;
}
public function setPhoto($photo)
{
$this->photo = $photo;
}
public function getNotes()
{
return $this->notes;
}
public function setNotes($notes)
{
$this->notes = $notes;
}
public function getPosition(): string
{
return $this->info->getCurrentPosition();
}
public function getCompany(): string
{
return $this->info->getCurrentCompany();
}
public function getSalary(): int
{
return $this->info->getSalary();
}
public function setCurrentContacts(Contacts $contacts):void
{
$this->contacts = $contacts;
}
public function getCurrentContacts(): Contacts
{
return $this->contacts;
}
public function getContacts(): array
{
return $this->contacts->getAll();
}
public function getSkills(): array
{
return $this->skills->getAll();
}
public function getDocuments(): array
{
return $this->documents->getAll();
}
public function addDocument(File $file): array
{
$this->documents[] = $file;
return $this->documents;
}
public function setCurrentDocuments(Documents $documents):void
{
$this->documents = $documents;
}
public function getCurrentDocuments(): Documents
{
return $this->documents;
}
/**** ******************************************** ***/
public function getCurrentSkills(): Skills
{
return clone $this->skills;
}
public function setCurrentSkills(Skills $skills)
{
$this->skills = $skills;
}
/*** OLD METHOD **/
private function setSkills(array $skills=[])
{
if(!empty($skills)) {
$new_skills=[];
/**создадим скиллы из массива*/
foreach ($skills as $skill){
$new_skills[]=new SkillCandidate((int)$skill);
}
/**удалим скилл если его нету в новом массиве*/
foreach ($this->skills->getAll() as $key => $old_skill) {
if (!in_array($old_skill->skill_id, $skills)) {
$this->skills->remove($key);
}
}
/**добавим скилл */
foreach ($new_skills as $new_skill) {
try {
$this->skills->add($new_skill);
}
catch (\DomainException $de) {
//TODO:
}
}
} else {
/**удалим все*/
foreach ($this->skills->getAll() as $key=>$skill) {
$this->skills->remove($key);
}
}
}
public function getSkillsToString(): string
{
$data = '';
foreach ($this->getSkills() as $skill) {
$data.= "<span class='skill'>{$skill->skill->name}</span>";
}
return $data;
}
private function prepareContacts(): array
{
$data = [];
foreach ($this->getContacts() as $key=>$value) {
$data[$value->type->name.$key] = $value->value;
}
return $data;
}
public function export(): array
{
$data = [
'salary' => $this->getSalary(),
'location' => $this->city->name??null,
];
$contacts = $this->prepareContacts();
$data = array_merge($data,$contacts);
$data['skills']= $this->getSkillsToString();
return $data;
}
public function getType(): string
{
return "candidate";
}
/**
* @return array
*/
public function releaseEvents(): array
{
// TODO: Implement releaseEvents() method.
return [];
}
/***##SERVICE METHODS **/
/**
* @inheritdoc
*/
public static function tableName()
{
return '{{%candidates}}';
}
/**
* @inheritdoc
*/
public function behaviors()
{
return [
[
'class' => SaveRelationsBehavior::className(),
'relations' => ['relatedContacts','relatedSkills','relatedDocuments'],
],
];
}
public function transactions(): array
{
return [
self::SCENARIO_DEFAULT => self::OP_ALL,
];
}
public function afterFind(): void
{
$this->id = new CandidateId(
$this->getAttribute('id')
);
$this->name = new Name(
$this->getAttribute('lastname'),
$this->getAttribute('name'),
$this->getAttribute('fathername')
);
$this->info = new Info(
$this->getAttribute('salary'),
$this->getAttribute('company'),
$this->getAttribute('position'),
new \DateTimeImmutable($this->getAttribute('date_birth'))
);
$this->createDate = new \DateTimeImmutable(
$this->getAttribute('date_created')
);
$this->photo = $this->getAttribute('photo');
$this->notes = $this->getAttribute('notes');
/*$this->birthDate = new \DateTimeImmutable(
$this->getAttribute('date_birth')
);*/
$this->current_status = $this->getAttribute('current_status');
$this->contacts = self::getLazyFactory()->createProxy(
Contacts::class,
function(&$target, LazyLoadingInterface $proxy) {
$target = new Contacts($this->relatedContacts);
$proxy->setProxyInitializer(null);
}
);
$this->skills = self::getLazyFactory()->createProxy(
Skills::class,
function(&$target, LazyLoadingInterface $proxy) {
$target = new Skills($this->relatedSkills);
$proxy->setProxyInitializer(null);
}
);
// $documents = $this->getAttribute('documents');
$this->documents = self::getLazyFactory()->createProxy(
Documents::class,
function(&$target, LazyLoadingInterface $proxy) {
$target = new Documents($this->relatedDocuments);
$proxy->setProxyInitializer(null);
}
);
// if(is_array($documents)) {
// $this->documents = File::find()->where(['id' => $documents])->all();
// } else {
// $this->documents = [];
// }
parent::afterFind();
}
public function beforeSave($insert): bool
{
$this->setAttribute('id', $this->id->getId() );
$this->setAttribute('lastname', $this->name->getLast() );
$this->setAttribute('name', $this->name->getFirst() );
$this->setAttribute('fathername', $this->name->getFather() );
$this->setAttribute('current_status',$this->getCurrentStatus() );
$this->setAttribute('date_created', $this->getCreateDate()->format('Y-m-d H:i:s') );
$this->setAttribute('date_birth', $this->getBirthDate()->format('Y-m-d') );
$this->setAttribute('salary', $this->info->getSalary());
$this->setAttribute('company', $this->info->getCurrentCompany() );
$this->setAttribute('position', $this->info->getCurrentPosition() );
$this->setAttribute('photo', $this->getPhoto());
$this->setAttribute('notes', $this->getNotes());
/*
if(isset($this->documents)){
$documents = [];
foreach($this->getDocuments() as $document) {
// $documents[] = $document->id;
$documents[] = $document;
}
$this->setAttribute('documents', $documents);
}
*/
if (!$this->documents instanceOf LazyLoadingInterface || $this->documents->isProxyInitialized()) {
$this->relatedDocuments = $this->documents->getAll();
}
if (!$this->contacts instanceOf LazyLoadingInterface || $this->contacts->isProxyInitialized()) {
$this->relatedContacts = $this->contacts->getAll();
}
if (!$this->skills instanceOf LazyLoadingInterface || $this->skills->isProxyInitialized()) {
$this->relatedSkills = $this->skills->getAll();
}
// TODO: remove these comments
// $lastInsertedId = \Yii::$app->db->createCommand('SELECT MAX(id) FROM files_uploaded')->queryScalar();
//
// $model = \common\models\File::findOne(['id' => $lastInsertedId]);
// $model->entity_id = $this->getId()->getId();
// $model->save();
return parent::beforeSave($insert);
}
/***RELATIONS***/
public function getRelatedContacts(): ActiveQuery
{
return $this->hasMany(ContactCandidate::className(), ['candidate_id'=>'id'])->orderBy('contact_type');
}
public function getRelatedSkills(): ActiveQuery
{
return $this->hasMany(SkillCandidate::className(), ['candidate_id' => 'id'])->orderBy('skill_id');
}
public function getRelatedDocuments(): ActiveQuery
{
return $this->hasMany(DocumentCandidate::className(), ['entity_id' => 'id'])->orderBy('entity_id');
}
public function getCity()
{
return $this->hasOne(City::className(),['id'=>'location']);
}
}
Я попытался задать в ней правила следующим образом:
public function scenarios()
{
return [
self::SCENARIO_DEFAULT => ['id','name','lastname','fathername','location','current_status','company','position','salary','date_birth','date_created','photo','wish','documents','notes'],
];
}
public function rules()
{
return [
[['id','name','lastname','fathername','location','current_status','company','position','salary','date_birth','date_created','photo','wish','documents','notes'], 'safe','on' => 'update'],
];
}
Все равно не могу избавиться от ошибки и соответственно данные не обновляются. Буду признателен за любые ответы!
У тебя - какой шаблон - basic? А попробуй-ка подключить yii\web\JsonParser:
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => 'KkDF5NnbNMGCSH96cwn3ROrgil-6Z36N',
'csrfParam' => '_csrf-frontend',
'parsers' => [
'application/json' => 'yii\web\JsonParser',
],
],
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Нужно чтобы шла проверка по всем пользователям в таблице (ban_drivers) по колонке (ban_do) если значение в (ban_do) у какого-то пользователя совпадает...
Я использую PHP на nginxКакие права должны быть установлена для папки сессий? Сейчас права 777 - это позволяет создавать и записывать сессии, но мне...
Ребят, в бд есть таблица с названием фильтров - sorting (поля: id, title), с пунктами фильтров - options (поля: id, sorting_id - id фильтра, title), таблица с товарами...
в БД есть таблица с данными продуктов из которых для каждого продукта должны выводиться определённые данныеНо в продуктах все данные повторяются