Exemple #1
0
 protected function log($message)
 {
     if (!class_exists('\\rock\\log\\Log')) {
         return;
     }
     $message = BaseException::convertExceptionToString(new ValidateException($message));
     Log::warn($message);
 }
Exemple #2
0
 /**
  * @inheritdoc
  */
 public function validate($input = null)
 {
     /* @var $targetClass ActiveRecordInterface */
     $targetClass = $this->targetClass === null ? get_class($this->model) : $this->targetClass;
     $targetAttribute = $this->targetAttribute === null ? $this->attribute : $this->targetAttribute;
     if (is_array($targetAttribute)) {
         $params = [];
         foreach ($targetAttribute as $k => $v) {
             $params[$v] = is_integer($k) ? $this->model->{$v} : $this->model->{$k};
         }
         $this->params['value'] = $params;
     } else {
         $params = [$targetAttribute => $this->model[$this->attribute]];
         $this->params['value'] = $this->model[$this->attribute];
     }
     foreach ($params as $value) {
         if (is_array($value)) {
             if (class_exists('\\rock\\log\\Log')) {
                 $message = BaseException::convertExceptionToString(new ValidateException("{$targetClass}::{$targetAttribute} is invalid: type array()"));
                 Log::err($message);
             }
             return false;
         }
     }
     $query = $targetClass::find();
     $query->andWhere($params);
     if ($this->filter instanceof \Closure) {
         call_user_func($this->filter, $query);
     } elseif ($this->filter !== null) {
         $query->andWhere($this->filter);
     }
     if (!$this->model instanceof ActiveRecordInterface || $this->model->getIsNewRecord()) {
         // if current $model isn't in the database yet then it's OK just to call exists()
         $exists = $query->exists();
     } else {
         // if current $model is in the database already we can't use exists()
         /* @var $models ActiveRecordInterface[] */
         $models = $query->limit(2)->all();
         $n = count($models);
         if ($n === 1) {
             $keys = array_keys($params);
             $pks = $targetClass::primaryKey();
             sort($keys);
             sort($pks);
             if ($keys === $pks) {
                 // primary key is modified and not unique
                 $exists = $this->model->getOldPrimaryKey() != $this->model->getPrimaryKey();
             } else {
                 // non-primary key, need to exclude the current record based on PK
                 $exists = $models[0]->getPrimaryKey() != $this->model->getOldPrimaryKey();
             }
         } else {
             $exists = $n > 1;
         }
     }
     return !$exists;
 }
 /**
  * @param Mail $mail
  * @param Users $users
  * @param SignupForm $model
  */
 public function sendMail(Mail $mail, Users $users, SignupForm $model)
 {
     $subject = i18n::t('subjectRegistration', ['site_name' => i18n::t('siteName')]);
     $body = $this->prepareBody($model, $users);
     try {
         $mail->address($users->email)->subject($subject)->body($body)->send();
     } catch (\Exception $e) {
         $model->addError('alerts', i18n::t('failSendEmail'));
         Log::warn(BaseException::convertExceptionToString($e));
     }
 }
Exemple #4
0
 /**
  * Sends a http-query.
  * @param string $url
  * @param array $params
  * @return null|Response
  */
 public function send($url, array $params = [])
 {
     $params = array_merge(parse_url($url), $params);
     $request = $this->getRequest($params);
     try {
         $response = $this->getResponse($url, $params);
     } catch (BadResponseException $e) {
         if ($e->hasResponse()) {
             return $this->convertResponse($e->getResponse(), $request);
         }
         return null;
     } catch (\Exception $e) {
         if (class_exists('\\rock\\log\\Log')) {
             Log::warn(BaseException::convertExceptionToString($e));
         }
         return null;
     }
     return $this->convertResponse($response, $request);
 }
Exemple #5
0
 /**
  * {@inheritdoc}
  */
 public function getAttributes($code = null)
 {
     if (!isset($code)) {
         $code = Request::get('code');
     }
     if (empty($code)) {
         return [];
     }
     // This was a callback request from google, get the token
     $this->service->requestAccessToken($code);
     // Send a request with it
     try {
         return Json::decode($this->service->request($this->apiUrl));
     } catch (JsonException $e) {
         if (class_exists('\\rock\\log\\Log')) {
             Log::err(BaseException::convertExceptionToString($e));
         }
     }
     return [];
 }
Exemple #6
0
 /**
  * @inheritdoc
  */
 protected function generate($generate = false)
 {
     if (!empty($this->data) && $generate === false) {
         return $this->data;
     }
     $fonts = [];
     $fontsdir_absolute = dirname(__FILE__) . DIRECTORY_SEPARATOR . $this->fontsDir;
     if ($handle = opendir($fontsdir_absolute)) {
         while (false !== ($file = readdir($handle))) {
             if (preg_match('/\\.png$/i', $file)) {
                 $fonts[] = $fontsdir_absolute . DIRECTORY_SEPARATOR . $file;
             }
         }
         closedir($handle);
     }
     $alphabet = self::ALPHABET_FONT;
     $alphabet_length = strlen($alphabet);
     // generating random keystring
     do {
         while (true) {
             $this->code = null;
             for ($i = 0; $i < $this->length; ++$i) {
                 $this->code .= $this->alphabet[mt_rand(0, strlen($this->alphabet) - 1)];
             }
             if (!preg_match('/cp|cb|ck|c6|c9|rn|rm|mm|co|do|cl|db|qp|qb|dp|ww/', $this->code)) {
                 break;
             }
         }
         $font_file = $fonts[mt_rand(0, count($fonts) - 1)];
         $font = imagecreatefrompng($font_file);
         imagealphablending($font, true);
         $fontfile_width = imagesx($font);
         $fontfile_height = imagesy($font) - 1;
         $font_metrics = [];
         $symbol = 0;
         $reading_symbol = false;
         // loading font
         for ($i = 0; $i < $fontfile_width && $symbol < $alphabet_length; ++$i) {
             $transparent = imagecolorat($font, $i, 0) >> 24 == 127;
             if (empty($reading_symbol) && empty($transparent)) {
                 $font_metrics[$alphabet[$symbol]] = ['start' => $i];
                 $reading_symbol = true;
                 continue;
             } elseif (!empty($reading_symbol) && !empty($transparent)) {
                 $font_metrics[$alphabet[$symbol]]['end'] = $i;
                 $reading_symbol = false;
                 ++$symbol;
                 continue;
             }
         }
         $img = imagecreatetruecolor($this->width, $this->height);
         imagealphablending($img, true);
         $white = imagecolorallocate($img, 255, 255, 255);
         $black = imagecolorallocate($img, 0, 0, 0);
         imagefilledrectangle($img, 0, 0, $this->width - 1, $this->height - 1, $white);
         // draw text
         $x = 1;
         $odd = mt_rand(0, 1);
         if ($odd == 0) {
             $odd = -1;
         }
         for ($i = 0; $i < $this->length; ++$i) {
             $m = $font_metrics[$this->code[$i]];
             $y = ($i % 2 * $this->fluctuationAmplitude - $this->fluctuationAmplitude / 2) * $odd + mt_rand(-round($this->fluctuationAmplitude / 3), round($this->fluctuationAmplitude / 3)) + ($this->height - $fontfile_height) / 2;
             if ($this->noSpaces === true) {
                 $shift = 0;
                 if ($i > 0) {
                     $shift = 10000;
                     for ($sy = 3; $sy < $fontfile_height - 10; $sy += 1) {
                         for ($sx = $m['start'] - 1; $sx < $m['end']; $sx += 1) {
                             $rgb = imagecolorat($font, $sx, $sy);
                             $opacity = $rgb >> 24;
                             if ($opacity < 127) {
                                 $left = $sx - $m['start'] + $x;
                                 $py = $sy + $y;
                                 if ($py > $this->height) {
                                     break;
                                 }
                                 for ($px = min($left, $this->width - 1); $px > $left - 200 && $px >= 0; $px -= 1) {
                                     $color = imagecolorat($img, $px, $py) & 0xff;
                                     if ($color + $opacity < 170) {
                                         // 170 - threshold
                                         if ($shift > $left - $px) {
                                             $shift = $left - $px;
                                         }
                                         break;
                                     }
                                 }
                                 break;
                             }
                         }
                     }
                     if ($shift == 10000) {
                         $shift = mt_rand(4, 6);
                     }
                 }
             } else {
                 $shift = 1;
             }
             imagecopy($img, $font, $x - $shift, $y, $m['start'], 1, $m['end'] - $m['start'], $fontfile_height);
             $x += $m['end'] - $m['start'] - $shift;
         }
     } while ($x >= $this->width - 10);
     // while not fit in canvas
     // noise
     $white = imagecolorallocate($font, 255, 255, 255);
     $black = imagecolorallocate($font, 0, 0, 0);
     for ($i = 0; $i < ($this->height - 30) * $x * $this->whiteNoiseDensity; ++$i) {
         imagesetpixel($img, mt_rand(0, $x - 1), mt_rand(10, $this->height - 15), $white);
     }
     for ($i = 0; $i < ($this->height - 30) * $x * $this->blackNoiseDensity; ++$i) {
         imagesetpixel($img, mt_rand(0, $x - 1), mt_rand(10, $this->height - 15), $black);
     }
     $center = $x / 2;
     // credits. To remove, see configuration file
     $img2 = imagecreatetruecolor($this->width, $this->height + ($this->showCredits === true ? 12 : 0));
     $foreground = imagecolorallocate($img2, $this->foregroundColor[0], $this->foregroundColor[1], $this->foregroundColor[2]);
     $background = imagecolorallocate($img2, $this->backgroundColor[0], $this->backgroundColor[1], $this->backgroundColor[2]);
     imagefilledrectangle($img2, 0, 0, $this->width - 1, $this->height - 1, $background);
     imagefilledrectangle($img2, 0, $this->height, $this->width - 1, $this->height + 12, $foreground);
     $credits = empty($credits) ? $_SERVER['HTTP_HOST'] : $credits;
     imagestring($img2, 2, $this->width / 2 - imagefontwidth(2) * strlen($credits) / 2, $this->height - 2, $credits, $background);
     // periods
     $rand1 = mt_rand(750000, 1200000) / 10000000;
     $rand2 = mt_rand(750000, 1200000) / 10000000;
     $rand3 = mt_rand(750000, 1200000) / 10000000;
     $rand4 = mt_rand(750000, 1200000) / 10000000;
     // phases
     $rand5 = mt_rand(0, 31415926) / 10000000;
     $rand6 = mt_rand(0, 31415926) / 10000000;
     $rand7 = mt_rand(0, 31415926) / 10000000;
     $rand8 = mt_rand(0, 31415926) / 10000000;
     // amplitudes
     $rand9 = mt_rand(330, 420) / 110;
     $rand10 = mt_rand(330, 450) / 100;
     // wave distortion
     for ($x = 0; $x < $this->width; ++$x) {
         for ($y = 0; $y < $this->height; ++$y) {
             $sx = $x + (sin($x * $rand1 + $rand5) + sin($y * $rand3 + $rand6)) * $rand9 - $this->width / 2 + $center + 1;
             $sy = $y + (sin($x * $rand2 + $rand7) + sin($y * $rand4 + $rand8)) * $rand10;
             if ($sx < 0 || $sy < 0 || $sx >= $this->width - 1 || $sy >= $this->height - 1) {
                 continue;
             } else {
                 $color = imagecolorat($img, $sx, $sy) & 0xff;
                 $color_x = imagecolorat($img, $sx + 1, $sy) & 0xff;
                 $color_y = imagecolorat($img, $sx, $sy + 1) & 0xff;
                 $color_xy = imagecolorat($img, $sx + 1, $sy + 1) & 0xff;
             }
             if ($color == 255 && $color_x == 255 && $color_y == 255 && $color_xy == 255) {
                 continue;
             } elseif ($color === 0 && $color_x === 0 && $color_y === 0 && $color_xy === 0) {
                 $newred = $this->foregroundColor[0];
                 $newgreen = $this->foregroundColor[1];
                 $newblue = $this->foregroundColor[2];
             } else {
                 $frsx = $sx - floor($sx);
                 $frsy = $sy - floor($sy);
                 $frsx1 = 1 - $frsx;
                 $frsy1 = 1 - $frsy;
                 $newcolor = $color * $frsx1 * $frsy1 + $color_x * $frsx * $frsy1 + $color_y * $frsx1 * $frsy + $color_xy * $frsx * $frsy;
                 if ($newcolor > 255) {
                     $newcolor = 255;
                 }
                 $newcolor = $newcolor / 255;
                 $newcolor0 = 1 - $newcolor;
                 $newred = $newcolor0 * $this->foregroundColor[0] + $newcolor * $this->backgroundColor[0];
                 $newgreen = $newcolor0 * $this->foregroundColor[1] + $newcolor * $this->backgroundColor[1];
                 $newblue = $newcolor0 * $this->foregroundColor[2] + $newcolor * $this->backgroundColor[2];
             }
             imagesetpixel($img2, $x, $y, imagecolorallocate($img2, $newred, $newgreen, $newblue));
         }
     }
     ob_start();
     if (function_exists('imagejpeg')) {
         $result['mimeType'] = 'image/jpeg';
         imagejpeg($img2, null, $this->quality);
     } elseif (function_exists('imagegif')) {
         $result['mimeType'] = 'image/gif';
         imagegif($img2);
     } elseif (function_exists('imagepng')) {
         $result['mimeType'] = 'image/x-png';
         imagepng($img2);
     }
     $result['image'] = ob_get_clean();
     if (empty($result['image'])) {
         if (class_exists('\\rock\\log\\Log')) {
             $message = BaseException::convertExceptionToString(new CaptchaException(CaptchaException::UNKNOWN_VAR, ['name' => '$return[\'image\']']));
             Log::warn($message);
         }
         return [];
     }
     return $this->data = $result;
 }
Exemple #7
0
 /**
  * PHP magic method that returns the string representation of this object.
  *
  * @return string the string representation of this object.
  */
 public function __toString()
 {
     // __toString cannot throw exception
     // use trigger_error to bypass this limitation
     try {
         return $this->render();
     } catch (\Exception $e) {
         if (class_exists('\\rock\\log\\Log')) {
             Log::err(BaseException::convertExceptionToString($e));
         }
         return '';
     }
 }
Exemple #8
0
 /**
  * @inheritdoc
  */
 public function lock($key, $iteration = 15)
 {
     $i = 0;
     while (!$this->lockInternal($key)) {
         $i++;
         if ($i > $iteration) {
             if (class_exists('\\rock\\log\\Log')) {
                 $message = BaseException::convertExceptionToString(new CacheException(CacheException::INVALID_SAVE, ['key' => $key]));
                 Log::err($message);
             }
             return false;
         }
         usleep(rand(10, 1000));
     }
     return true;
 }
Exemple #9
0
 /**
  * Commits a transaction.
  *
  * @throws DbException if the transaction is not active
  */
 public function commit()
 {
     if (!$this->getIsActive()) {
         throw new DbException('Failed to commit transaction: transaction was inactive.');
     }
     $this->_level--;
     if ($this->_level == 0) {
         Trace::trace('db', ['msg' => 'Commit transaction', 'method' => __METHOD__]);
         $this->connection->pdo->commit();
         $this->connection->trigger(Connection::EVENT_COMMIT_TRANSACTION);
         return;
     }
     $schema = $this->connection->getSchema();
     if ($schema->supportsSavepoint()) {
         Trace::trace('db', ['msg' => 'Release savepoint ' . $this->_level, 'method' => __METHOD__]);
         $schema->releaseSavepoint('LEVEL' . $this->_level);
     } else {
         if (class_exists('\\rock\\log\\Log')) {
             $message = BaseException::convertExceptionToString(new DbException('Transaction not committed: nested transaction not supported'));
             Log::info($message);
         }
     }
 }
Exemple #10
0
 /**
  * Is self domain.
  *
  * @param bool $throw throw an exception (default: false)
  * @throws RequestException
  * @return bool
  */
 public function isSelfDomain($throw = false)
 {
     if (!($domains = $this->allowDomains)) {
         return true;
     }
     if (!in_array(strtolower($_SERVER['SERVER_NAME']), $domains, true) || !in_array(strtolower($_SERVER['HTTP_HOST']), $domains, true)) {
         if ($throw === true) {
             throw new RequestException("Invalid domain: {$_SERVER['HTTP_HOST']}");
         } else {
             if (class_exists('\\rock\\log\\Log')) {
                 $message = BaseException::convertExceptionToString(new RequestException("Invalid domain: {$_SERVER['HTTP_HOST']}"));
                 Log::err($message);
             }
         }
         return false;
     }
     return true;
 }
Exemple #11
0
 /**
  * Session write handler.
  * Do not call this method directly.
  * @param string $id session ID
  * @param string $data session data
  * @return boolean whether session write is successful
  */
 public function writeSession($id, $data)
 {
     // exception must be caught in session write handler
     // http://us.php.net/manual/en/function.session-set-save-handler.php
     try {
         $this->connection->getCollection($this->sessionCollection)->update(['id' => $id], ['id' => $id, 'data' => $data, 'expire' => new \MongoDate(time() + $this->getTimeout())], ['upsert' => true]);
     } catch (\Exception $e) {
         if (class_exists('\\rock\\log\\Log')) {
             Log::warn(BaseException::convertExceptionToString($e));
         }
         return false;
     }
     return true;
 }
Exemple #12
0
 protected function prepareImage($path)
 {
     $metadata = $this->adapter->getMetadata($path);
     $path = implode(DIRECTORY_SEPARATOR, [trim($metadata['dirname'], DIRECTORY_SEPARATOR), "{$this->width}x{$this->height}", $metadata['basename']]);
     $this->src = $this->srcCache . '/' . ltrim($path, '/');
     if ($this->adapterCache->has($path)) {
         return;
     }
     if ($this->handler instanceof \Closure) {
         call_user_func($this->handler, $path, $this);
         return;
     }
     $string = Image::thumbnail($this->image, $this->width, $this->height)->get('jpg');
     if (!$this->adapterCache->write($path, $string)) {
         if (class_exists('\\rock\\log\\Log')) {
             $message = BaseException::convertExceptionToString(new ImageException(ImageException::NOT_CREATE_FILE, ['path' => $path]));
             Log::warn($message);
         }
     }
 }
Exemple #13
0
 /**
  * Session write handler.
  *
  * Do not call this method directly.
  * @param string $id session ID
  * @param string $data session data
  * @return boolean whether session write is successful
  */
 public function writeSession($id, $data)
 {
     // exception must be caught in session write handler
     // http://us.php.net/manual/en/function.session-set-save-handler.php
     try {
         $expire = time() + $this->getTimeout();
         $exists = (new Query())->select(['id'])->from($this->sessionTable)->where(['id' => $id])->createCommand($this->connection)->queryScalar();
         if ($exists === null) {
             $this->connection->createCommand()->insert($this->sessionTable, ['id' => $id, 'data' => $data, 'expire' => $expire])->execute();
         } else {
             $this->connection->createCommand()->update($this->sessionTable, ['data' => $data, 'expire' => $expire], ['id' => $id])->execute();
         }
     } catch (\Exception $e) {
         if (class_exists('\\rock\\log\\Log')) {
             Log::warn(BaseException::convertExceptionToString($e));
         }
         return false;
     }
     return true;
 }
Exemple #14
0
 /**
  * @param \Exception $exception
  * @param int $level
  * @param Response $response
  */
 public static function display(\Exception $exception, $level = Log::CRITICAL, Response $response = null)
 {
     // append log
     if (static::$logged) {
         Log::log($level, BaseException::convertExceptionToString($exception));
     }
     // display Whoops
     if (ROCK_DEBUG === true) {
         static::debuger($response)->handleException($exception);
         return;
     }
     // else display fatal
     static::displayFatal($response);
 }
Exemple #15
0
 /**
  * @inheritdoc
  */
 public function send($message = '', $limit = -1)
 {
     if (!$this->beforeSend()) {
         return null;
     }
     $client = $this->client();
     if ($this->blocking) {
         $result = null;
         switch ($this->priority) {
             case self::PRIORITY_NORMAL:
                 $result = $client->doNormal($this->id, $message);
                 break;
             case self::PRIORITY_LOW:
                 $result = $client->doLow($this->id, $message);
                 break;
             default:
                 $result = $client->doHigh($this->id, $message);
                 break;
         }
         $this->afterSend($result);
         return $result;
     } else {
         $count = 0;
         $client->setTimeout($this->timeout * 1000);
         while ($limit == -1 || $count < $limit) {
             switch ($this->priority) {
                 case self::PRIORITY_NORMAL:
                     $result = @$client->doNormal($this->id, $message);
                     break;
                 case self::PRIORITY_LOW:
                     $result = @$client->doLow($this->id, $message);
                     break;
                 default:
                     $result = @$client->doHigh($this->id, $message);
                     break;
             }
             if ($result) {
                 $this->afterSend($result);
                 return $result;
             }
             ++$count;
         }
     }
     if (class_exists('\\rock\\log\\Log')) {
         $message = BaseException::convertExceptionToString(new MQException('The receive timed out.'));
         Log::err($message);
     }
     return null;
 }
Exemple #16
0
 /**
  * Opens the connection to a server in the pool.
  *
  * This method implements the load balancing among the given list of the servers.
  *
  * @param array $pool the list of connection configurations in the server pool
  * @param array $sharedConfig the configuration common to those given in `$pool`.
  * @return Connection the opened DB connection, or null if no server is available
  * @throws DbException if a configuration does not specify "dsn"
  */
 protected function openFromPool(array $pool, array $sharedConfig)
 {
     if (empty($pool)) {
         return null;
     }
     if (!isset($sharedConfig['class'])) {
         $sharedConfig['class'] = get_class($this);
     }
     $cache = Instance::ensure($this->serverStatusCache, null, [], false);
     shuffle($pool);
     foreach ($pool as $config) {
         $config = array_merge($sharedConfig, $config);
         if (empty($config['dsn'])) {
             throw new DbException('The "dsn" option must be specified.');
         }
         $key = [__METHOD__, $config['dsn']];
         if ($cache instanceof CacheInterface && $cache->get($key)) {
             // should not try this dead server now
             continue;
         }
         /* @var $connection Connection */
         $connection = Instance::ensure($config);
         try {
             $connection->open();
             return $connection;
         } catch (\Exception $e) {
             if (class_exists('\\rock\\log\\Log')) {
                 Log::warn(BaseException::convertExceptionToString($e));
             }
             if ($cache instanceof CacheInterface) {
                 // mark this server as dead and only retry it after the specified interval
                 $cache->set($key, 1, $this->serverRetryInterval);
             }
         }
     }
     return null;
 }
Exemple #17
0
 /**
  * @inheritdoc
  */
 public function subscribe($topic = '', $limit = 1, $message = '')
 {
     if (!$this->beforeSubscription($topic, $message)) {
         return null;
     }
     $connection = new AMQPConnection($this->host, $this->port, $this->user, $this->password);
     $channel = $connection->channel();
     $channel->exchange_declare($this->exchange, $this->type, false, false, false);
     list($queueName) = $channel->queue_declare("", false, false, true, false);
     $correlationId = uniqid();
     $result = null;
     $channel->basic_consume($queueName, '', false, false, false, false, function (AMQPMessage $msg) use(&$result, $correlationId) {
         if ($msg->get('correlation_id') == $correlationId) {
             $result = $msg->body;
         }
     });
     register_shutdown_function(function (AMQPChannel $channel, AMQPConnection $connection) {
         $channel->close();
         $connection->close();
     }, $channel, $connection);
     $msg = new AMQPMessage($message, ['correlation_id' => $correlationId, 'reply_to' => $queueName]);
     $channel->basic_publish($msg, $this->exchange, $topic);
     if ($this->blocking) {
         if (count($channel->callbacks)) {
             $channel->wait();
         }
         $this->afterSubscription($topic, $result);
         return $result;
     }
     // non-blocking
     if (count($channel->callbacks)) {
         $count = 0;
         while ($limit == -1 || $count < $limit) {
             // add here other sockets that you need to attend
             $read = [];
             if (is_resource($connection->getSocket())) {
                 $read = [$connection->getSocket()];
             }
             $write = null;
             $except = null;
             if (false === ($num_changed_streams = stream_select($read, $write, $except, $this->timeout))) {
                 break;
             } elseif ($num_changed_streams > 0) {
                 $channel->wait();
                 $this->afterSubscription($topic, $result);
                 return $result;
             }
             ++$count;
         }
         if (class_exists('\\rock\\log\\Log')) {
             $message = BaseException::convertExceptionToString(new MQException('The receive timed out.'));
             Log::err($message);
         }
     }
     return $result;
 }
Exemple #18
0
 /**
  * Saves the changes to this active record into the associated database table.
  *
  * This method performs the following steps in order:
  *
  * 1. call {@see \rock\components\Model::beforeValidate()} when `$runValidation` is true. If validation
  *    fails, it will skip the rest of the steps;
  * 2. call {@see \rock\components\Model::afterValidate()} when `$runValidation` is true.
  * 3. call {@see \rock\db\common\BaseActiveRecord::beforeSave()}. If the method returns false, it will skip the
  *    rest of the steps;
  * 4. save the record into database. If this fails, it will skip the rest of the steps;
  * 5. call {@see \rock\db\common\BaseActiveRecord::afterSave()};
  *
  * In the above step 1, 2, 3 and 5, events {@see \rock\components\Model::EVENT_BEFORE_VALIDATE},
  * {@see \rock\db\common\BaseActiveRecord::EVENT_BEFORE_UPDATE}, {@see \rock\db\common\BaseActiveRecord::EVENT_AFTER_UPDATE} and {@see \rock\components\Model::EVENT_AFTER_VALIDATE}
  * will be raised by the corresponding methods.
  *
  * Only the {@see \rock\db\common\BaseActiveRecord::$dirtyAttributes}(changed attribute values) will be saved into database.
  *
  * For example, to update a customer record:
  *
  * ```php
  * $customer = Customer::findOne($id);
  * $customer->name = $name;
  * $customer->email = $email;
  * $customer->update();
  * ```
  *
  * Note that it is possible the update does not affect any row in the table.
  * In this case, this method will return 0. For this reason, you should use the following
  * code to check if update() is successful or not:
  *
  * ```php
  * if ($this->update() !== false) {
  *     // update successful
  * } else {
  *     // update failed
  * }
  * ```
  *
  * @param boolean $runValidation whether to perform validation before saving the record.
  * If the validation fails, the record will not be inserted into the database.
  * @param array $attributeNames list of attributes that need to be saved. Defaults to null,
  * meaning all attributes that are loaded from DB will be saved.
  * @return integer|boolean the number of rows affected, or false if validation fails
  * or {@see \rock\db\common\BaseActiveRecord::beforeSave()} stops the updating process.
  * @throws DbException if {@see \rock\db\common\BaseActiveRecord::optimisticLock()}(optimistic locking) is enabled and the data
  * being updated is outdated.
  * @throws \Exception in case update failed.
  */
 public function update($runValidation = true, array $attributeNames = null)
 {
     if ($runValidation && !$this->validate($attributeNames)) {
         if (class_exists('\\rock\\log\\Log')) {
             $message = BaseException::convertExceptionToString(new DbException('Model not updated due to validation error.'));
             Log::info($message);
         }
         return false;
     }
     if (!$this->isTransactional(self::OP_UPDATE)) {
         return $this->updateInternal($attributeNames);
     }
     $transaction = static::getConnection()->beginTransaction();
     try {
         $result = $this->updateInternal($attributeNames);
         if ($result === false) {
             $transaction->rollBack();
         } else {
             $transaction->commit();
         }
         return $result;
     } catch (\Exception $e) {
         $transaction->rollBack();
         throw $e;
     }
 }
Exemple #19
0
 /**
  * Logout user.
  * @param bool $destroy destroy session.
  */
 public function logout($destroy = true)
 {
     if (!$this->enableSession) {
         return;
     }
     $ip = $this->request->getUserIP();
     $id = $this->get('id');
     Log::info(BaseException::convertExceptionToString(new BaseException("User '{$id}' logged out from {$ip}.")));
     if ($destroy === true && $this->storage instanceof Session) {
         $this->storage->destroy();
         return;
     }
     $this->removeAll();
 }
Exemple #20
0
 /**
  * @inheritdoc
  * @throws MQException
  */
 public function subscribe($topic = '', $limit = -1, $message = '')
 {
     if (!$this->beforeSubscription($topic, $message)) {
         return null;
     }
     $subscriber = $this->connection(\ZMQ::SOCKET_SUB);
     $subscriber->setSockOpt(\ZMQ::SOCKOPT_SUBSCRIBE, $topic);
     if ($this->blocking) {
         $result = $subscriber->recvMulti();
         $result = isset($result[1]) ? $result[1] : null;
         $this->afterSubscription($topic, $result);
         return $result;
     }
     $count = 0;
     while ($limit == -1 || $count < $limit) {
         try {
             $result = $subscriber->recvMulti(\ZMQ::MODE_DONTWAIT);
             if (!empty($result)) {
                 $result = isset($result[1]) ? $result[1] : null;
                 $this->afterSubscription($topic, $result);
                 return $result;
             }
         } catch (\ZMQSocketException $e) {
             throw new MQException($e->getMessage(), [], $e);
         }
         ++$count;
         sleep($this->timeout);
     }
     if (class_exists('\\rock\\log\\Log')) {
         $message = BaseException::convertExceptionToString(new MQException('The receive timed out.'));
         Log::err($message);
     }
     return null;
 }
Exemple #21
0
 /**
  * @inheritdoc
  */
 public function lock($key, $iteration = 15)
 {
     $i = 0;
     while (!apc_add($this->prepareKey($key, self::LOCK_PREFIX), 1, $this->lockExpire)) {
         $i++;
         if ($i > $iteration) {
             if (class_exists('\\rock\\log\\Log')) {
                 $message = BaseException::convertExceptionToString(new CacheException(CacheException::INVALID_SAVE, ['key' => $key]));
                 Log::err($message);
             }
             return false;
         }
         usleep(rand(10, 1000));
     }
     return true;
 }
Exemple #22
0
 /**
  * Modify URL.
  *
  * @param string|null $url URL for formatting. If URL as `NULL`, then use current (self) URL.
  * @param array $config
  * @throws UrlException
  * @throws \Exception
  * @throws \rock\helpers\InstanceException
  */
 public function __construct($url = null, $config = [])
 {
     $this->parentConstruct($config);
     $this->request = Instance::ensure($this->request, '\\rock\\request\\Request');
     $this->csrfInstance = Instance::ensure($this->csrfInstance, '\\rock\\csrf\\CSRF', [], false);
     if (empty($url)) {
         $url = $this->currentInternal();
     } else {
         $url = Alias::getAlias($url);
     }
     if (($url = parse_url(trim($url))) === false) {
         $exception = new UrlException('Wrong format URL.');
         if ($this->throwException) {
             throw $exception;
         } else {
             if (class_exists('\\rock\\log\\Log')) {
                 \rock\log\Log::warn(BaseException::convertExceptionToString($exception));
             }
             $url = parse_url(trim($this->currentInternal()));
             $url['fragment'] = '#';
         }
     }
     $this->data = array_merge($url, $this->data);
     if (isset($this->data['query'])) {
         $this->data['query'] = $this->_queryToArray($this->data['query']);
     }
 }