/** * @inheritdoc */ protected function getValue($event) { if (is_string($this->value) && method_exists($this->owner, $this->value)) { $value = call_user_func([$this->owner, $this->value], $event); } else { $value = is_callable($this->value) ? call_user_func($this->value, $event) : $this->value; } $group = md5(serialize(['class' => $this->unique ? get_class($this->owner) : false, 'group' => $this->group, 'attribute' => $this->attribute, 'value' => $value])); do { $repeat = false; try { $model = AutoNumber::findOne($group); if ($model) { $number = $model->number + 1; } else { $model = new AutoNumber(['group' => $group]); $number = 1; } $model->update_time = time(); $model->number = $number; $model->save(false); } catch (Exception $exc) { if ($exc instanceof StaleObjectException) { $repeat = true; } else { throw $exc; } } } while ($repeat); if ($value === null) { return $number; } else { return str_replace('?', $this->digit ? sprintf("%0{$this->digit}d", $number) : $number, $value); } }
/** * Handle for [[\yii\db\ActiveRecord::EVENT_BEFORE_INSERT]] and [[\yii\db\ActiveRecord::EVENT_BEFORE_UPDATE]] * @param \yii\base\ModelEvent $event */ public function beforeSave($event) { list($id, $attribute) = $event->data; if (isset(self::$_executed[$id])) { return; } /* @var $object \yii\db\ActiveRecord */ $object = $event->sender; if (is_string($this->format) && method_exists($object, $this->format)) { $value = call_user_func([$object, $this->format], $object, $attribute); } else { $value = is_callable($this->format) ? call_user_func($this->format, $object, $attribute) : $this->format; } $group = md5(serialize(['class' => $this->unique ? get_class($object) : false, 'group' => $this->group, 'attribute' => $attribute, 'value' => $value])); $model = AutoNumber::findOne($group); if ($model) { $number = $model->number + 1; } else { $model = new AutoNumber(['group' => $group]); $number = 1; } $model->update_time = time(); $model->number = $number; if ($value === null) { $object->{$attribute} = $number; } else { $object->{$attribute} = str_replace('?', $this->digit ? sprintf("%0{$this->digit}d", $number) : $number, $value); } self::$_executed[$id] = true; try { $model->save(false); } catch (\Exception $exc) { $event->isValid = false; if ($this->throwIsStale || !$exc instanceof StaleObjectException) { throw $exc; } } }