#0 | Image\Storage->checkOriginalExists(/www/wiki.youvivu.com/public_html/public/img/original/publication/0/479_1732325296.jpg) /www/wiki.youvivu.com/public_html/app/modules/Image/Storage.php (331) <?php namespace Image; use Phalcon\Mvc\User\Component; define('IMG_ROOT_REL_PATH', 'img'); define('DIR_SEP', '/'); define('IMG_ROOT_PATH', ROOT . DIR_SEP); define('IMG_STORAGE_SERVER', ''); define('IMG_EXTENSION', 'jpg'); define('NOIMAGE', '/static/images/noimage.jpg'); define('IMG_DEBUG_MODE', true); class Storage extends Component { private static $STRATEGIES = [ 'w', // Масштабируем по ширине 'wh', // Масштабируем по заданной ширине и высоте. Изображение подганяется в этот прямоугольник 'a', // Центрируем и обрезаем изображение по заданной высоте и ширине таким образом, чтоб оно полностью заполнило пространство ]; private $id = null; private $image_hash = null; private $type = 'publication'; private $strategy = 'w'; private $width = 100; private $height = null; private $hash = false; private $attributes = []; private $exists = true; private $widthHeight = true; private $stretch = true; public function __construct(array $params = [], array $attributes = []) { $this->setIdFromParams($params); $this->attributes = $attributes; $this->type = (isset($params['type'])) ? $params['type'] : 'publication'; $this->strategy = (isset($params['strategy'])) ? $params['strategy'] : 'w'; $this->image_hash = (isset($params['image_hash'])) ? $params['image_hash'] : null; $this->hash = (isset($params['hash'])) ? $params['hash'] : false; $this->setDimensionsAttributes($params); } private function setDimensionsAttributes(array $params = []) { $this->width = (isset($params['width'])) ? $params['width'] : 100; $this->height = (isset($params['height'])) ? $params['height'] : null; $this->widthHeight = (isset($params['widthHeight'])) ? $params['widthHeight'] : true; $this->widthHeight = (isset($params['widthHeight']) && MOBILE_DEVICE) ? false : true; $this->stretch = (isset($params['stretch'])) ? $params['stretch'] : null; } private function setIdFromParams($params) { if (isset($params['id'])) { if (preg_match('/^\d+$/', $params['id'])) { $this->id = (int) $params['id']; } else { $this->id = $params['id']; } } else { if (IMG_DEBUG_MODE) { throw new \Exception("ID не определен"); } } } /** * HTML-тег изображения, готовый к использованию * <img src="" alt="" /> */ public function imageHtml() { //Из заданных параметров и атрибутов составляем html-тэг $this->attributesForImageHtml(); // Получаем относительный адрес файла кешированного изображения $src = $this->cachedRelPath(); if ($this->exists) { if ($this->hash) { $src .= '?' . microtime(); } } else { $src = NOIMAGE; $this->attributes['width'] = $this->width; $this->attributes['height'] = $this->height; } $attr_src = 'src="' . $this->getDi()->get('config')->base_path . $src . '"'; $result = '<img ' . $attr_src . $this->attributesResultForImageHtml($this->attributes) . '/>'; return $result; } private function attributesForImageHtml() { if ($this->widthHeight) { if ($this->stretch && in_array($this->strategy, ['wh', 'a'])) { $this->stretch = false; } $this->changeAttributesInAccordanceWithStretch(); } $this->attributes['alt'] = (isset($this->attributes['alt'])) ? htmlspecialchars($this->attributes['alt'], ENT_QUOTES) : ''; } private function changeAttributesInAccordanceWithStretch() { if ($this->stretch) { $this->changeAttributesForStretch(); } else { $this->changeAttributesWithoutStretch(); } } private function changeAttributesForStretch() { if ($this->width) { $this->attributes['width'] = $this->width; } if ($this->height) { $this->attributes['height'] = $this->height; } } private function changeAttributesWithoutStretch() { $widthHeight = $this->getImageWidthHeight(); if ($widthHeight['width']) { $this->attributes['width'] = $widthHeight['width']; } if ($widthHeight['height']) { $this->attributes['height'] = $widthHeight['height']; } } private function attributesResultForImageHtml($attributes) { $attributesHtmlArray = []; foreach ($attributes as $el => $val) { $attributesHtmlArray[] = $el . '="' . $val . '"'; } $attributesHtml = implode(' ', $attributesHtmlArray); $attributesHtmlResult = ($attributesHtml) ? ' ' . $attributesHtml : ''; return $attributesHtmlResult; } /** * Относительный адрес файла кешированного изображения * /img/preview/405102/405102_1_w_100.jpg */ public function cachedRelPath() { // Рассчитываем по входящим параметрам относительный путь к кешированному файлу $cachedRelPath = $this->calculateCachedRelPath(); // Совмещаем относительный путь с корневым, получаем абсолютный путь $cachedAbsPath = IMG_ROOT_PATH . $cachedRelPath; // Проверяем существование такого файла. если файл не существует: if (!file_exists($cachedAbsPath)) { // Генерируем кеш-файл по заданным параметрам $this->generateCachedImage(); } return IMG_STORAGE_SERVER . $cachedRelPath; } /** * @return string */ public function cachedAbsPath() { return IMG_ROOT_PATH . $this->cachedRelPath(); } /** * Относительный адрес файла оригинального изображения */ public function originalRelPath() { return IMG_STORAGE_SERVER . $this->calculateOriginalRelPath(); } /** * Абсолютный адрес файла оригинального изображения */ public function originalAbsPath() { return $this->getAbsPath(true); } /** * @param $file * @return bool */ public function save($file) { if (file_exists($file)) { return copy($file, $this->originalAbsPath()); } } /** * @return array */ public function originalWidthHeight() { $imageSize = getimagesize($this->originalAbsPath()); if (!empty($imageSize)) { return [ 'width' => $imageSize[0], 'height' => $imageSize[1] ]; } } /** * @return int */ public function cachedFileSize() { $path = $this->cachedAbsPath(); if (file_exists($path)) { return filesize($path); } } /** * @return bool */ public function isExists() { return (file_exists($this->getAbsPath(true))) ? true : false ; } /** * Рассчитываем по входящим параметрам относительный путь к кешированному файлу * /img/preview/405/405102_1_w_100.jpg */ private function calculateCachedRelPath() { $pathParts = []; $pathParts[] = IMG_ROOT_REL_PATH; $pathParts[] = 'cache'; $pathParts[] = $this->type; if (is_int($this->id)) { $idPart = floor($this->id / 1000); } else { $idPart = $this->id; } $pathParts[] = $idPart; $fileParts = []; $fileParts[] = $this->id; if ($this->image_hash) { $fileParts[] = $this->image_hash; } if (in_array($this->strategy, self::$STRATEGIES)) { $fileParts[] = $this->strategy; $fileParts[] = $this->width; if ($this->height) { $fileParts[] = $this->height; } // "img/preview/405" $path = implode(DIR_SEP, $pathParts); // "405102_1_w_100" $file = implode('_', $fileParts); return $path . DIR_SEP . $file . '.jpg'; } else { if (IMG_DEBUG_MODE) { throw new \Exception("Параметр 'strategy' указан неверно"); } } } /** * Рассчитываем по входящим параметрам относительный путь к оригинальному файлу * /img/original/preview/405/405102_1.jpg * @return string */ private function calculateOriginalRelPath() { $pathParts = []; $pathParts[] = IMG_ROOT_REL_PATH; $pathParts[] = 'original'; $pathParts[] = $this->type; if (is_int($this->id)) { $idPart = floor($this->id / 1000); } else { $idPart = $this->id; } $pathParts[] = $idPart; $fileParts = []; $fileParts[] = $this->id; if ($this->image_hash) { $fileParts[] = $this->image_hash; } // "img/original/preview/405" $path = implode(DIR_SEP, $pathParts); // "405102_1" $file = implode('_', $fileParts); return $path . DIR_SEP . $file . '_' . time() . '.jpg'; } /** * генерируем кеш-файл по заданным параметрам * @throws \Exception */ private function generateCachedImage() { // Абсолютный путь оригинального изображения $originalAbsPath = IMG_ROOT_PATH . $this->calculateOriginalRelPath(); $this->checkOriginalExists($originalAbsPath); require_once __DIR__ . '/PHPThumb/ThumbLib.inc.php'; $image = \PhpThumbFactory::create($originalAbsPath); // Для мобильных устройств отдаем изображение с качеством на уровне 60% if (MOBILE_DEVICE) { $options = ['jpegQuality' => 60]; $image->setOptions($options); } switch ($this->strategy) { case 'w': // Масштабируем по ширине $image->resize($this->width); break; case 'wh': // Масштабируем по заданной ширине и высоте. Изображение подганяется в этот прямоугольник $image->resize($this->width, $this->height); break; case 'a': // Центрируем и обрезаем изображение по заданной высоте и ширине таким образом, чтоб оно полностью заполнило пространство $image->adaptiveResize($this->width, $this->height); break; } $this->saveImage($image, $originalAbsPath); } /** * @param $left * @param $top * @param $width * @param $height * @throws \Exception */ public function cropOriginal($left, $top, $width, $height) { $originalAbsPath = IMG_ROOT_PATH . $this->calculateOriginalRelPath(); // Абсолютный путь оригинального изображения $this->checkOriginalExists($originalAbsPath); require_once __DIR__ . '/PHPThumb/ThumbLib.inc.php'; $image = \PhpThumbFactory::create($originalAbsPath); $image->crop($left, $top, $width, $height); $this->saveImage($image, $originalAbsPath); } /** * @param $originalAbsPath * @throws \Exception */ private function checkOriginalExists($originalAbsPath) { if (!file_exists($originalAbsPath)) { if (IMG_DEBUG_MODE) { throw new \Exception("Файл {$originalAbsPath} не существует"); } else { $this->exists = false; } } } /** * @param $image * @param $originalAbsPath * @throws \Exception */ private function saveImage($image, $originalAbsPath) { // Если оригинал не заблокирован, блокируем. Это необходимо для предотвращения множественной генерации кеш-файла параллельными запросами if ($this->lockOriginal($originalAbsPath)) { // Сохраняем кешированное изображение $image->save($this->getAbsPath(false)); // Снимаем блокировку $this->unlockOriginal($originalAbsPath); } else { if (IMG_DEBUG_MODE) { throw new \Exception("Файл {$originalAbsPath} заблокирован механизмом проверки _LOCK или не существует"); } else { $this->exists = false; } } } /** * Удаляет оригинальные и кешированные изображения * @param bool $removeAll */ public function remove($removeAll = true) { $this->removeCached(); $this->removeOriginal($removeAll); } /** * Удаляет оригинальные изображения * @param bool $removeAll */ public function removeOriginal($removeAll = true) { if (!$removeAll) { if (file_exists($this->originalAbsPath())) { unlink($this->originalAbsPath()); } } else { $originalAbsPath = IMG_ROOT_PATH . $this->calculateOriginalRelPath(); $originalAbsPathDir = implode(DIR_SEP, array_slice(explode(DIR_SEP, $originalAbsPath), 0, -1)); // Абсолютный путь директории if ($this->image_hash) { $search = $originalAbsPathDir . "/" . $this->id . "_*.jpg"; } else { $search = $originalAbsPathDir . "/" . $this->id . ".jpg"; } $files = glob($search); if (!empty($files)) { foreach ($files as $file) { if (is_file($file)) { unlink($file); } } } } } /** * Удаляет кешированные изображения */ public function removeCached() { $cachedAbsPath = IMG_ROOT_PATH . $this->calculateCachedRelPath(); $cachedAbsPathDir = implode(DIR_SEP, array_slice(explode(DIR_SEP, $cachedAbsPath), 0, -1)); // Абсолютный путь директории $search = $cachedAbsPathDir . "/" . $this->id . "_*.jpg"; $files = glob($search); if (!empty($files)) { foreach ($files as $file) { if (is_file($file)) { unlink($file); } } } } /** * Размеры кешированного изображения */ public function getImageWidthHeight() { $cachedAbsPath = IMG_ROOT_PATH . $this->calculateCachedRelPath(); if (file_exists($cachedAbsPath)) { $imageSize = getimagesize($cachedAbsPath); if (!empty($imageSize)) { return [ 'width' => $imageSize[0], 'height' => $imageSize[1] ]; } } else { return [ 'width' => null, 'height' => null ]; } } /** * Проверяем блокировку оригинала изображения. Если нет, то блокируем * @param string $originalAbsPath * @return boolean true|false */ private function lockOriginal($originalAbsPath) { $lockFileName = $this->getLockFileName($originalAbsPath); if (file_exists($lockFileName)) { return false; } else { $handle = fopen($lockFileName, 'w+'); if (flock($handle, LOCK_EX)) { fwrite($handle, '1'); flock($handle, LOCK_UN); fclose($handle); return true; } else { if ($handle) { fclose($handle); } return false; } } } /** * Снимаем блокировку оригинала изображения * @param string $originalAbsPath */ private function unlockOriginal($originalAbsPath) { unlink($this->getLockFileName($originalAbsPath)); } /** * Возвращает имя файла для блокировки оригинала изображения * @param string $originalAbsPath * @return string */ private function getLockFileName($originalAbsPath) { return preg_replace('/\.' . IMG_EXTENSION . '/i', '_lock.' . IMG_EXTENSION, $originalAbsPath); } /** * @param bool $original * @return string * @throws \Exception */ private function getAbsPath($original = true) { $absPath = IMG_ROOT_PATH . (($original) ? $this->calculateOriginalRelPath() : $this->calculateCachedRelPath()); // Абсолютный путь директории $absPathDir = implode(DIR_SEP, array_slice(explode(DIR_SEP, $absPath), 0, -1)); // Если директория отсутствует if (!is_dir($absPathDir)) { // Создаем дерево директорий mkdir($absPathDir, 0777, true); } return $absPath; } /** * @param bool $original * @return string * @throws \Exception */ public function getabsPathDir($original = true) { $absPath = IMG_ROOT_PATH . (($original) ? $this->calculateOriginalRelPath() : $this->calculateCachedRelPath()); // Абсолютный путь директории $absPathDir = implode(DIR_SEP, array_slice(explode(DIR_SEP, $absPath), 0, -1)); // Если директория отсутствует if (!is_dir($absPathDir)) { // Создаем дерево директорий mkdir($absPathDir, 0777, true); } return $absPathDir; } } |
#1 | Image\Storage->generateCachedImage() /www/wiki.youvivu.com/public_html/app/modules/Image/Storage.php (171) <?php namespace Image; use Phalcon\Mvc\User\Component; define('IMG_ROOT_REL_PATH', 'img'); define('DIR_SEP', '/'); define('IMG_ROOT_PATH', ROOT . DIR_SEP); define('IMG_STORAGE_SERVER', ''); define('IMG_EXTENSION', 'jpg'); define('NOIMAGE', '/static/images/noimage.jpg'); define('IMG_DEBUG_MODE', true); class Storage extends Component { private static $STRATEGIES = [ 'w', // Масштабируем по ширине 'wh', // Масштабируем по заданной ширине и высоте. Изображение подганяется в этот прямоугольник 'a', // Центрируем и обрезаем изображение по заданной высоте и ширине таким образом, чтоб оно полностью заполнило пространство ]; private $id = null; private $image_hash = null; private $type = 'publication'; private $strategy = 'w'; private $width = 100; private $height = null; private $hash = false; private $attributes = []; private $exists = true; private $widthHeight = true; private $stretch = true; public function __construct(array $params = [], array $attributes = []) { $this->setIdFromParams($params); $this->attributes = $attributes; $this->type = (isset($params['type'])) ? $params['type'] : 'publication'; $this->strategy = (isset($params['strategy'])) ? $params['strategy'] : 'w'; $this->image_hash = (isset($params['image_hash'])) ? $params['image_hash'] : null; $this->hash = (isset($params['hash'])) ? $params['hash'] : false; $this->setDimensionsAttributes($params); } private function setDimensionsAttributes(array $params = []) { $this->width = (isset($params['width'])) ? $params['width'] : 100; $this->height = (isset($params['height'])) ? $params['height'] : null; $this->widthHeight = (isset($params['widthHeight'])) ? $params['widthHeight'] : true; $this->widthHeight = (isset($params['widthHeight']) && MOBILE_DEVICE) ? false : true; $this->stretch = (isset($params['stretch'])) ? $params['stretch'] : null; } private function setIdFromParams($params) { if (isset($params['id'])) { if (preg_match('/^\d+$/', $params['id'])) { $this->id = (int) $params['id']; } else { $this->id = $params['id']; } } else { if (IMG_DEBUG_MODE) { throw new \Exception("ID не определен"); } } } /** * HTML-тег изображения, готовый к использованию * <img src="" alt="" /> */ public function imageHtml() { //Из заданных параметров и атрибутов составляем html-тэг $this->attributesForImageHtml(); // Получаем относительный адрес файла кешированного изображения $src = $this->cachedRelPath(); if ($this->exists) { if ($this->hash) { $src .= '?' . microtime(); } } else { $src = NOIMAGE; $this->attributes['width'] = $this->width; $this->attributes['height'] = $this->height; } $attr_src = 'src="' . $this->getDi()->get('config')->base_path . $src . '"'; $result = '<img ' . $attr_src . $this->attributesResultForImageHtml($this->attributes) . '/>'; return $result; } private function attributesForImageHtml() { if ($this->widthHeight) { if ($this->stretch && in_array($this->strategy, ['wh', 'a'])) { $this->stretch = false; } $this->changeAttributesInAccordanceWithStretch(); } $this->attributes['alt'] = (isset($this->attributes['alt'])) ? htmlspecialchars($this->attributes['alt'], ENT_QUOTES) : ''; } private function changeAttributesInAccordanceWithStretch() { if ($this->stretch) { $this->changeAttributesForStretch(); } else { $this->changeAttributesWithoutStretch(); } } private function changeAttributesForStretch() { if ($this->width) { $this->attributes['width'] = $this->width; } if ($this->height) { $this->attributes['height'] = $this->height; } } private function changeAttributesWithoutStretch() { $widthHeight = $this->getImageWidthHeight(); if ($widthHeight['width']) { $this->attributes['width'] = $widthHeight['width']; } if ($widthHeight['height']) { $this->attributes['height'] = $widthHeight['height']; } } private function attributesResultForImageHtml($attributes) { $attributesHtmlArray = []; foreach ($attributes as $el => $val) { $attributesHtmlArray[] = $el . '="' . $val . '"'; } $attributesHtml = implode(' ', $attributesHtmlArray); $attributesHtmlResult = ($attributesHtml) ? ' ' . $attributesHtml : ''; return $attributesHtmlResult; } /** * Относительный адрес файла кешированного изображения * /img/preview/405102/405102_1_w_100.jpg */ public function cachedRelPath() { // Рассчитываем по входящим параметрам относительный путь к кешированному файлу $cachedRelPath = $this->calculateCachedRelPath(); // Совмещаем относительный путь с корневым, получаем абсолютный путь $cachedAbsPath = IMG_ROOT_PATH . $cachedRelPath; // Проверяем существование такого файла. если файл не существует: if (!file_exists($cachedAbsPath)) { // Генерируем кеш-файл по заданным параметрам $this->generateCachedImage(); } return IMG_STORAGE_SERVER . $cachedRelPath; } /** * @return string */ public function cachedAbsPath() { return IMG_ROOT_PATH . $this->cachedRelPath(); } /** * Относительный адрес файла оригинального изображения */ public function originalRelPath() { return IMG_STORAGE_SERVER . $this->calculateOriginalRelPath(); } /** * Абсолютный адрес файла оригинального изображения */ public function originalAbsPath() { return $this->getAbsPath(true); } /** * @param $file * @return bool */ public function save($file) { if (file_exists($file)) { return copy($file, $this->originalAbsPath()); } } /** * @return array */ public function originalWidthHeight() { $imageSize = getimagesize($this->originalAbsPath()); if (!empty($imageSize)) { return [ 'width' => $imageSize[0], 'height' => $imageSize[1] ]; } } /** * @return int */ public function cachedFileSize() { $path = $this->cachedAbsPath(); if (file_exists($path)) { return filesize($path); } } /** * @return bool */ public function isExists() { return (file_exists($this->getAbsPath(true))) ? true : false ; } /** * Рассчитываем по входящим параметрам относительный путь к кешированному файлу * /img/preview/405/405102_1_w_100.jpg */ private function calculateCachedRelPath() { $pathParts = []; $pathParts[] = IMG_ROOT_REL_PATH; $pathParts[] = 'cache'; $pathParts[] = $this->type; if (is_int($this->id)) { $idPart = floor($this->id / 1000); } else { $idPart = $this->id; } $pathParts[] = $idPart; $fileParts = []; $fileParts[] = $this->id; if ($this->image_hash) { $fileParts[] = $this->image_hash; } if (in_array($this->strategy, self::$STRATEGIES)) { $fileParts[] = $this->strategy; $fileParts[] = $this->width; if ($this->height) { $fileParts[] = $this->height; } // "img/preview/405" $path = implode(DIR_SEP, $pathParts); // "405102_1_w_100" $file = implode('_', $fileParts); return $path . DIR_SEP . $file . '.jpg'; } else { if (IMG_DEBUG_MODE) { throw new \Exception("Параметр 'strategy' указан неверно"); } } } /** * Рассчитываем по входящим параметрам относительный путь к оригинальному файлу * /img/original/preview/405/405102_1.jpg * @return string */ private function calculateOriginalRelPath() { $pathParts = []; $pathParts[] = IMG_ROOT_REL_PATH; $pathParts[] = 'original'; $pathParts[] = $this->type; if (is_int($this->id)) { $idPart = floor($this->id / 1000); } else { $idPart = $this->id; } $pathParts[] = $idPart; $fileParts = []; $fileParts[] = $this->id; if ($this->image_hash) { $fileParts[] = $this->image_hash; } // "img/original/preview/405" $path = implode(DIR_SEP, $pathParts); // "405102_1" $file = implode('_', $fileParts); return $path . DIR_SEP . $file . '_' . time() . '.jpg'; } /** * генерируем кеш-файл по заданным параметрам * @throws \Exception */ private function generateCachedImage() { // Абсолютный путь оригинального изображения $originalAbsPath = IMG_ROOT_PATH . $this->calculateOriginalRelPath(); $this->checkOriginalExists($originalAbsPath); require_once __DIR__ . '/PHPThumb/ThumbLib.inc.php'; $image = \PhpThumbFactory::create($originalAbsPath); // Для мобильных устройств отдаем изображение с качеством на уровне 60% if (MOBILE_DEVICE) { $options = ['jpegQuality' => 60]; $image->setOptions($options); } switch ($this->strategy) { case 'w': // Масштабируем по ширине $image->resize($this->width); break; case 'wh': // Масштабируем по заданной ширине и высоте. Изображение подганяется в этот прямоугольник $image->resize($this->width, $this->height); break; case 'a': // Центрируем и обрезаем изображение по заданной высоте и ширине таким образом, чтоб оно полностью заполнило пространство $image->adaptiveResize($this->width, $this->height); break; } $this->saveImage($image, $originalAbsPath); } /** * @param $left * @param $top * @param $width * @param $height * @throws \Exception */ public function cropOriginal($left, $top, $width, $height) { $originalAbsPath = IMG_ROOT_PATH . $this->calculateOriginalRelPath(); // Абсолютный путь оригинального изображения $this->checkOriginalExists($originalAbsPath); require_once __DIR__ . '/PHPThumb/ThumbLib.inc.php'; $image = \PhpThumbFactory::create($originalAbsPath); $image->crop($left, $top, $width, $height); $this->saveImage($image, $originalAbsPath); } /** * @param $originalAbsPath * @throws \Exception */ private function checkOriginalExists($originalAbsPath) { if (!file_exists($originalAbsPath)) { if (IMG_DEBUG_MODE) { throw new \Exception("Файл {$originalAbsPath} не существует"); } else { $this->exists = false; } } } /** * @param $image * @param $originalAbsPath * @throws \Exception */ private function saveImage($image, $originalAbsPath) { // Если оригинал не заблокирован, блокируем. Это необходимо для предотвращения множественной генерации кеш-файла параллельными запросами if ($this->lockOriginal($originalAbsPath)) { // Сохраняем кешированное изображение $image->save($this->getAbsPath(false)); // Снимаем блокировку $this->unlockOriginal($originalAbsPath); } else { if (IMG_DEBUG_MODE) { throw new \Exception("Файл {$originalAbsPath} заблокирован механизмом проверки _LOCK или не существует"); } else { $this->exists = false; } } } /** * Удаляет оригинальные и кешированные изображения * @param bool $removeAll */ public function remove($removeAll = true) { $this->removeCached(); $this->removeOriginal($removeAll); } /** * Удаляет оригинальные изображения * @param bool $removeAll */ public function removeOriginal($removeAll = true) { if (!$removeAll) { if (file_exists($this->originalAbsPath())) { unlink($this->originalAbsPath()); } } else { $originalAbsPath = IMG_ROOT_PATH . $this->calculateOriginalRelPath(); $originalAbsPathDir = implode(DIR_SEP, array_slice(explode(DIR_SEP, $originalAbsPath), 0, -1)); // Абсолютный путь директории if ($this->image_hash) { $search = $originalAbsPathDir . "/" . $this->id . "_*.jpg"; } else { $search = $originalAbsPathDir . "/" . $this->id . ".jpg"; } $files = glob($search); if (!empty($files)) { foreach ($files as $file) { if (is_file($file)) { unlink($file); } } } } } /** * Удаляет кешированные изображения */ public function removeCached() { $cachedAbsPath = IMG_ROOT_PATH . $this->calculateCachedRelPath(); $cachedAbsPathDir = implode(DIR_SEP, array_slice(explode(DIR_SEP, $cachedAbsPath), 0, -1)); // Абсолютный путь директории $search = $cachedAbsPathDir . "/" . $this->id . "_*.jpg"; $files = glob($search); if (!empty($files)) { foreach ($files as $file) { if (is_file($file)) { unlink($file); } } } } /** * Размеры кешированного изображения */ public function getImageWidthHeight() { $cachedAbsPath = IMG_ROOT_PATH . $this->calculateCachedRelPath(); if (file_exists($cachedAbsPath)) { $imageSize = getimagesize($cachedAbsPath); if (!empty($imageSize)) { return [ 'width' => $imageSize[0], 'height' => $imageSize[1] ]; } } else { return [ 'width' => null, 'height' => null ]; } } /** * Проверяем блокировку оригинала изображения. Если нет, то блокируем * @param string $originalAbsPath * @return boolean true|false */ private function lockOriginal($originalAbsPath) { $lockFileName = $this->getLockFileName($originalAbsPath); if (file_exists($lockFileName)) { return false; } else { $handle = fopen($lockFileName, 'w+'); if (flock($handle, LOCK_EX)) { fwrite($handle, '1'); flock($handle, LOCK_UN); fclose($handle); return true; } else { if ($handle) { fclose($handle); } return false; } } } /** * Снимаем блокировку оригинала изображения * @param string $originalAbsPath */ private function unlockOriginal($originalAbsPath) { unlink($this->getLockFileName($originalAbsPath)); } /** * Возвращает имя файла для блокировки оригинала изображения * @param string $originalAbsPath * @return string */ private function getLockFileName($originalAbsPath) { return preg_replace('/\.' . IMG_EXTENSION . '/i', '_lock.' . IMG_EXTENSION, $originalAbsPath); } /** * @param bool $original * @return string * @throws \Exception */ private function getAbsPath($original = true) { $absPath = IMG_ROOT_PATH . (($original) ? $this->calculateOriginalRelPath() : $this->calculateCachedRelPath()); // Абсолютный путь директории $absPathDir = implode(DIR_SEP, array_slice(explode(DIR_SEP, $absPath), 0, -1)); // Если директория отсутствует if (!is_dir($absPathDir)) { // Создаем дерево директорий mkdir($absPathDir, 0777, true); } return $absPath; } /** * @param bool $original * @return string * @throws \Exception */ public function getabsPathDir($original = true) { $absPath = IMG_ROOT_PATH . (($original) ? $this->calculateOriginalRelPath() : $this->calculateCachedRelPath()); // Абсолютный путь директории $absPathDir = implode(DIR_SEP, array_slice(explode(DIR_SEP, $absPath), 0, -1)); // Если директория отсутствует if (!is_dir($absPathDir)) { // Создаем дерево директорий mkdir($absPathDir, 0777, true); } return $absPathDir; } } |
#2 | Image\Storage->cachedRelPath() /www/wiki.youvivu.com/public_html/app/modules/Image/Storage.php (85) <?php namespace Image; use Phalcon\Mvc\User\Component; define('IMG_ROOT_REL_PATH', 'img'); define('DIR_SEP', '/'); define('IMG_ROOT_PATH', ROOT . DIR_SEP); define('IMG_STORAGE_SERVER', ''); define('IMG_EXTENSION', 'jpg'); define('NOIMAGE', '/static/images/noimage.jpg'); define('IMG_DEBUG_MODE', true); class Storage extends Component { private static $STRATEGIES = [ 'w', // Масштабируем по ширине 'wh', // Масштабируем по заданной ширине и высоте. Изображение подганяется в этот прямоугольник 'a', // Центрируем и обрезаем изображение по заданной высоте и ширине таким образом, чтоб оно полностью заполнило пространство ]; private $id = null; private $image_hash = null; private $type = 'publication'; private $strategy = 'w'; private $width = 100; private $height = null; private $hash = false; private $attributes = []; private $exists = true; private $widthHeight = true; private $stretch = true; public function __construct(array $params = [], array $attributes = []) { $this->setIdFromParams($params); $this->attributes = $attributes; $this->type = (isset($params['type'])) ? $params['type'] : 'publication'; $this->strategy = (isset($params['strategy'])) ? $params['strategy'] : 'w'; $this->image_hash = (isset($params['image_hash'])) ? $params['image_hash'] : null; $this->hash = (isset($params['hash'])) ? $params['hash'] : false; $this->setDimensionsAttributes($params); } private function setDimensionsAttributes(array $params = []) { $this->width = (isset($params['width'])) ? $params['width'] : 100; $this->height = (isset($params['height'])) ? $params['height'] : null; $this->widthHeight = (isset($params['widthHeight'])) ? $params['widthHeight'] : true; $this->widthHeight = (isset($params['widthHeight']) && MOBILE_DEVICE) ? false : true; $this->stretch = (isset($params['stretch'])) ? $params['stretch'] : null; } private function setIdFromParams($params) { if (isset($params['id'])) { if (preg_match('/^\d+$/', $params['id'])) { $this->id = (int) $params['id']; } else { $this->id = $params['id']; } } else { if (IMG_DEBUG_MODE) { throw new \Exception("ID не определен"); } } } /** * HTML-тег изображения, готовый к использованию * <img src="" alt="" /> */ public function imageHtml() { //Из заданных параметров и атрибутов составляем html-тэг $this->attributesForImageHtml(); // Получаем относительный адрес файла кешированного изображения $src = $this->cachedRelPath(); if ($this->exists) { if ($this->hash) { $src .= '?' . microtime(); } } else { $src = NOIMAGE; $this->attributes['width'] = $this->width; $this->attributes['height'] = $this->height; } $attr_src = 'src="' . $this->getDi()->get('config')->base_path . $src . '"'; $result = '<img ' . $attr_src . $this->attributesResultForImageHtml($this->attributes) . '/>'; return $result; } private function attributesForImageHtml() { if ($this->widthHeight) { if ($this->stretch && in_array($this->strategy, ['wh', 'a'])) { $this->stretch = false; } $this->changeAttributesInAccordanceWithStretch(); } $this->attributes['alt'] = (isset($this->attributes['alt'])) ? htmlspecialchars($this->attributes['alt'], ENT_QUOTES) : ''; } private function changeAttributesInAccordanceWithStretch() { if ($this->stretch) { $this->changeAttributesForStretch(); } else { $this->changeAttributesWithoutStretch(); } } private function changeAttributesForStretch() { if ($this->width) { $this->attributes['width'] = $this->width; } if ($this->height) { $this->attributes['height'] = $this->height; } } private function changeAttributesWithoutStretch() { $widthHeight = $this->getImageWidthHeight(); if ($widthHeight['width']) { $this->attributes['width'] = $widthHeight['width']; } if ($widthHeight['height']) { $this->attributes['height'] = $widthHeight['height']; } } private function attributesResultForImageHtml($attributes) { $attributesHtmlArray = []; foreach ($attributes as $el => $val) { $attributesHtmlArray[] = $el . '="' . $val . '"'; } $attributesHtml = implode(' ', $attributesHtmlArray); $attributesHtmlResult = ($attributesHtml) ? ' ' . $attributesHtml : ''; return $attributesHtmlResult; } /** * Относительный адрес файла кешированного изображения * /img/preview/405102/405102_1_w_100.jpg */ public function cachedRelPath() { // Рассчитываем по входящим параметрам относительный путь к кешированному файлу $cachedRelPath = $this->calculateCachedRelPath(); // Совмещаем относительный путь с корневым, получаем абсолютный путь $cachedAbsPath = IMG_ROOT_PATH . $cachedRelPath; // Проверяем существование такого файла. если файл не существует: if (!file_exists($cachedAbsPath)) { // Генерируем кеш-файл по заданным параметрам $this->generateCachedImage(); } return IMG_STORAGE_SERVER . $cachedRelPath; } /** * @return string */ public function cachedAbsPath() { return IMG_ROOT_PATH . $this->cachedRelPath(); } /** * Относительный адрес файла оригинального изображения */ public function originalRelPath() { return IMG_STORAGE_SERVER . $this->calculateOriginalRelPath(); } /** * Абсолютный адрес файла оригинального изображения */ public function originalAbsPath() { return $this->getAbsPath(true); } /** * @param $file * @return bool */ public function save($file) { if (file_exists($file)) { return copy($file, $this->originalAbsPath()); } } /** * @return array */ public function originalWidthHeight() { $imageSize = getimagesize($this->originalAbsPath()); if (!empty($imageSize)) { return [ 'width' => $imageSize[0], 'height' => $imageSize[1] ]; } } /** * @return int */ public function cachedFileSize() { $path = $this->cachedAbsPath(); if (file_exists($path)) { return filesize($path); } } /** * @return bool */ public function isExists() { return (file_exists($this->getAbsPath(true))) ? true : false ; } /** * Рассчитываем по входящим параметрам относительный путь к кешированному файлу * /img/preview/405/405102_1_w_100.jpg */ private function calculateCachedRelPath() { $pathParts = []; $pathParts[] = IMG_ROOT_REL_PATH; $pathParts[] = 'cache'; $pathParts[] = $this->type; if (is_int($this->id)) { $idPart = floor($this->id / 1000); } else { $idPart = $this->id; } $pathParts[] = $idPart; $fileParts = []; $fileParts[] = $this->id; if ($this->image_hash) { $fileParts[] = $this->image_hash; } if (in_array($this->strategy, self::$STRATEGIES)) { $fileParts[] = $this->strategy; $fileParts[] = $this->width; if ($this->height) { $fileParts[] = $this->height; } // "img/preview/405" $path = implode(DIR_SEP, $pathParts); // "405102_1_w_100" $file = implode('_', $fileParts); return $path . DIR_SEP . $file . '.jpg'; } else { if (IMG_DEBUG_MODE) { throw new \Exception("Параметр 'strategy' указан неверно"); } } } /** * Рассчитываем по входящим параметрам относительный путь к оригинальному файлу * /img/original/preview/405/405102_1.jpg * @return string */ private function calculateOriginalRelPath() { $pathParts = []; $pathParts[] = IMG_ROOT_REL_PATH; $pathParts[] = 'original'; $pathParts[] = $this->type; if (is_int($this->id)) { $idPart = floor($this->id / 1000); } else { $idPart = $this->id; } $pathParts[] = $idPart; $fileParts = []; $fileParts[] = $this->id; if ($this->image_hash) { $fileParts[] = $this->image_hash; } // "img/original/preview/405" $path = implode(DIR_SEP, $pathParts); // "405102_1" $file = implode('_', $fileParts); return $path . DIR_SEP . $file . '_' . time() . '.jpg'; } /** * генерируем кеш-файл по заданным параметрам * @throws \Exception */ private function generateCachedImage() { // Абсолютный путь оригинального изображения $originalAbsPath = IMG_ROOT_PATH . $this->calculateOriginalRelPath(); $this->checkOriginalExists($originalAbsPath); require_once __DIR__ . '/PHPThumb/ThumbLib.inc.php'; $image = \PhpThumbFactory::create($originalAbsPath); // Для мобильных устройств отдаем изображение с качеством на уровне 60% if (MOBILE_DEVICE) { $options = ['jpegQuality' => 60]; $image->setOptions($options); } switch ($this->strategy) { case 'w': // Масштабируем по ширине $image->resize($this->width); break; case 'wh': // Масштабируем по заданной ширине и высоте. Изображение подганяется в этот прямоугольник $image->resize($this->width, $this->height); break; case 'a': // Центрируем и обрезаем изображение по заданной высоте и ширине таким образом, чтоб оно полностью заполнило пространство $image->adaptiveResize($this->width, $this->height); break; } $this->saveImage($image, $originalAbsPath); } /** * @param $left * @param $top * @param $width * @param $height * @throws \Exception */ public function cropOriginal($left, $top, $width, $height) { $originalAbsPath = IMG_ROOT_PATH . $this->calculateOriginalRelPath(); // Абсолютный путь оригинального изображения $this->checkOriginalExists($originalAbsPath); require_once __DIR__ . '/PHPThumb/ThumbLib.inc.php'; $image = \PhpThumbFactory::create($originalAbsPath); $image->crop($left, $top, $width, $height); $this->saveImage($image, $originalAbsPath); } /** * @param $originalAbsPath * @throws \Exception */ private function checkOriginalExists($originalAbsPath) { if (!file_exists($originalAbsPath)) { if (IMG_DEBUG_MODE) { throw new \Exception("Файл {$originalAbsPath} не существует"); } else { $this->exists = false; } } } /** * @param $image * @param $originalAbsPath * @throws \Exception */ private function saveImage($image, $originalAbsPath) { // Если оригинал не заблокирован, блокируем. Это необходимо для предотвращения множественной генерации кеш-файла параллельными запросами if ($this->lockOriginal($originalAbsPath)) { // Сохраняем кешированное изображение $image->save($this->getAbsPath(false)); // Снимаем блокировку $this->unlockOriginal($originalAbsPath); } else { if (IMG_DEBUG_MODE) { throw new \Exception("Файл {$originalAbsPath} заблокирован механизмом проверки _LOCK или не существует"); } else { $this->exists = false; } } } /** * Удаляет оригинальные и кешированные изображения * @param bool $removeAll */ public function remove($removeAll = true) { $this->removeCached(); $this->removeOriginal($removeAll); } /** * Удаляет оригинальные изображения * @param bool $removeAll */ public function removeOriginal($removeAll = true) { if (!$removeAll) { if (file_exists($this->originalAbsPath())) { unlink($this->originalAbsPath()); } } else { $originalAbsPath = IMG_ROOT_PATH . $this->calculateOriginalRelPath(); $originalAbsPathDir = implode(DIR_SEP, array_slice(explode(DIR_SEP, $originalAbsPath), 0, -1)); // Абсолютный путь директории if ($this->image_hash) { $search = $originalAbsPathDir . "/" . $this->id . "_*.jpg"; } else { $search = $originalAbsPathDir . "/" . $this->id . ".jpg"; } $files = glob($search); if (!empty($files)) { foreach ($files as $file) { if (is_file($file)) { unlink($file); } } } } } /** * Удаляет кешированные изображения */ public function removeCached() { $cachedAbsPath = IMG_ROOT_PATH . $this->calculateCachedRelPath(); $cachedAbsPathDir = implode(DIR_SEP, array_slice(explode(DIR_SEP, $cachedAbsPath), 0, -1)); // Абсолютный путь директории $search = $cachedAbsPathDir . "/" . $this->id . "_*.jpg"; $files = glob($search); if (!empty($files)) { foreach ($files as $file) { if (is_file($file)) { unlink($file); } } } } /** * Размеры кешированного изображения */ public function getImageWidthHeight() { $cachedAbsPath = IMG_ROOT_PATH . $this->calculateCachedRelPath(); if (file_exists($cachedAbsPath)) { $imageSize = getimagesize($cachedAbsPath); if (!empty($imageSize)) { return [ 'width' => $imageSize[0], 'height' => $imageSize[1] ]; } } else { return [ 'width' => null, 'height' => null ]; } } /** * Проверяем блокировку оригинала изображения. Если нет, то блокируем * @param string $originalAbsPath * @return boolean true|false */ private function lockOriginal($originalAbsPath) { $lockFileName = $this->getLockFileName($originalAbsPath); if (file_exists($lockFileName)) { return false; } else { $handle = fopen($lockFileName, 'w+'); if (flock($handle, LOCK_EX)) { fwrite($handle, '1'); flock($handle, LOCK_UN); fclose($handle); return true; } else { if ($handle) { fclose($handle); } return false; } } } /** * Снимаем блокировку оригинала изображения * @param string $originalAbsPath */ private function unlockOriginal($originalAbsPath) { unlink($this->getLockFileName($originalAbsPath)); } /** * Возвращает имя файла для блокировки оригинала изображения * @param string $originalAbsPath * @return string */ private function getLockFileName($originalAbsPath) { return preg_replace('/\.' . IMG_EXTENSION . '/i', '_lock.' . IMG_EXTENSION, $originalAbsPath); } /** * @param bool $original * @return string * @throws \Exception */ private function getAbsPath($original = true) { $absPath = IMG_ROOT_PATH . (($original) ? $this->calculateOriginalRelPath() : $this->calculateCachedRelPath()); // Абсолютный путь директории $absPathDir = implode(DIR_SEP, array_slice(explode(DIR_SEP, $absPath), 0, -1)); // Если директория отсутствует if (!is_dir($absPathDir)) { // Создаем дерево директорий mkdir($absPathDir, 0777, true); } return $absPath; } /** * @param bool $original * @return string * @throws \Exception */ public function getabsPathDir($original = true) { $absPath = IMG_ROOT_PATH . (($original) ? $this->calculateOriginalRelPath() : $this->calculateCachedRelPath()); // Абсолютный путь директории $absPathDir = implode(DIR_SEP, array_slice(explode(DIR_SEP, $absPath), 0, -1)); // Если директория отсутствует if (!is_dir($absPathDir)) { // Создаем дерево директорий mkdir($absPathDir, 0777, true); } return $absPathDir; } } |
#3 | Image\Storage->imageHtml() /www/wiki.youvivu.com/public_html/data/cache/volt/%%www%%wiki.youvivu.com%%public_html%%app%%modules%%publication%%views%%index%%publication.volt.php (992) <style> .destination-container img { width: 100%; height: auto; } ul.listBlogInLocation li a img { float: left; padding: 1px; border: 1px solid #ddd; } ul.listBlogInLocation li a > img { width: 54px; } ul.listBlogInLocation li a span { float: left; width: 70%; margin-left: 5px; color: #777 !important; font-size: 13px !important; line-height: 18px; } ul#cat_nav.listBlogInLocation i { font-size: 13px !important; } .mfp-container { text-align: center; position: absolute; width: 100%; height: auto; left: 0; top: 0; padding: 0 8px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } #youviu-modal-culture-detail { background: #FFF; padding: 20px; width: auto; max-width: 840px; margin: 62px auto; } .mfp-close-btn-in .mfp-close { color: #333; background: #fff; } </style> <div class="mfp-bg mfp-ready"></div> <div class="mfp-wrap mfp-close-btn-in mfp-auto-cursor mfp-ready" tabindex="-1" style="overflow-x: hidden; overflow-y: auto; display: none"> <div class="mfp-container mfp-s-ready mfp-inline-holder"> <div class="mfp-content"> <div id="youviu-modal-culture-detail" class="white-popup"> <div class="body"> <div class="row"> <div class="col-md-12" id="cul_content"> </div> </div> </div> <button title="Close (Esc)" type="button" class="mfp-close">×</button> </div> </div> <div class="mfp-preloader">Loading...</div> </div> </div> <?php if (($publicationResult->p->getTypeSlug() != 'locations')) { ?> <section class="parallax-window" data-parallax="scroll" data-image-src="<?= $this->url->path() ?><?= $publicationResult->p->banner_src ?>" data-natural-width="1400" data-natural-height="470"> <div class="parallax-content-1"> <div class="animated fadeInDown"> <h1>KHÁM PHÁ VIỆT NAM</h1> <p>Hãy khám phá việt nam qua những địa điểm phượt vô cùng thú vị, thơ mộng và hùng vĩ.</p> </div> </div> </section><!-- End section --> <div class="container margin_60"> <div id="tour_guide"><p><img class="img-circle styled lazy" src="<?= $publicationResult->p->preview_src ?>" alt="<?= $publicationResult->title ?>" style="width: 250px; height: 250px; display: inline;" data-original="/<?= $publicationResult->p->preview_src ?>"></p> <span class="rating"><i class="icon-star voted"></i><i class="icon-star voted"></i><i class="icon-star voted"></i><i class="icon-star voted"></i><i class="icon-star-empty"></i></span> <h2>Khám phá <span><?= $publicationResult->title ?></span> Việt Nam</h2> <p class="lead destination-lead add_bottom_30"> <?= $publicationResult->p->meta_description ?>. </p></div> <div class="row"> <div class="col-md-8" id="single_tour_desc"> <h3>Nét đẹp <span><?= $publicationResult->title ?></span></h3> <p class="visible-sm visible-xs"><a class="btn_map" data-toggle="collapse" href="#collapseMap" aria-expanded="false" aria-controls="collapseMap" data-text-swap="Hide map" data-text-original="View on map">View on map</a></p><!-- Map button for tablets/mobiles --> <div class="row"> <div class="col-md-12 destination-container"> <?= $publicationResult->text ?> </div> </div> <div style="padding-top: 10px"> <div class="fb-like" data-href='<?php echo "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; ?>' data-layout="standard" data-action="like" data-size="small" data-show-faces="true" data-share="true"></div> <div style="width:100% !important;" class="fb-comments" data-href='<?php echo "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; ?>' data-numposts="5"></div> </div> </div><!--End single_tour_desc--> <aside class="col-md-4"> <p class="hidden-sm hidden-xs" style="display: none;"> <a class="btn_map" data-toggle="collapse" href="#collapseMap" aria-expanded="false" aria-controls="collapseMap" data-text-swap="Hide map" data-text-original="View on map">View on map</a> </p> <div style="display: none;"> <?php foreach($cul as $cu) { ?> <div id="cul_<?php echo $cu->id ?>" style="display: none;"><?php echo ($cu->text) ?></div> <?php } ?> </div> <div class="box_style_cat youviu-box-culture-common youviu-box-culture-destination"><h3 style="text-align: center">Văn hóa & con người</h3> <ul id="cat_nav" class="listBlogInLocation"> <?php foreach($cul as $cu) { ?> <li><a class="youviu-culture-popup-detail" rel="nofollow" data-title="<?php echo $cu->title ?>" data-href="showcul(<?php echo $cu->id ?>)" onclick="showcul(<?php echo $cu->id ?>)" href="javascript:void(0)"> <img style="width: 54px;height: 54px;" class="lazy" alt="<?php echo $cu->title ?>" data-original="/<?php echo $cu->preview_src ?>" src="/assets/ba871a56/img/loading.gif"><span> <?php echo $cu->title ?><br><div class="rating"><i class="icon-star voted"></i><i class="icon-star voted"></i><i class="icon-star voted"></i><i class="icon-star voted"></i><i class="icon-star-empty"></i></div><br><i class="icon-calendar-empty"></i> Đăng ngày 01/01/2017 </span> <div style="clear:both"></div> </a></li> <?php } ?> <div id="youviu-modal-culture-detail" class="white-popup mfp-hide"> <div class="body"></div> </div> </ul> </div> </aside> </div><!--End row --> </div><!--End container --> <article id="content" class="publication clearfix" style="display: none;"> <?php if ($this->helper->isAdminSession()) { ?> <p style="font-weight: bold;font-size:120%;"> <a class="noajax" href="<?= $this->url->get() ?>publication/admin/edit/<?= $publicationResult->p->getId() ?>?lang=<?= constant('LANG') ?>"><?= $this->helper->at('Edit publication') ?></a> </p> <?php } ?> <h1><?= $publicationResult->title ?></h1> <?php if ($publicationResult->p->getTypeDisplayDate()) { ?> <section class="date"><?= $publicationResult->p->getDate('d.m.Y') ?></section> <?php } ?> <?php if ($publicationResult->p->preview_inner) { ?> <?php $image = $this->helper->image(['id' => $publicationResult->p->getId(), 'type' => 'publication', 'width' => 300, 'strategy' => 'w']); ?> <div class="image inner"> <?= $image->imageHTML() ?> </div> <?php } ?> <?= $publicationResult->text ?> <a href="<?= $this->helper->langUrl(['for' => 'publications', 'type' => $publicationResult->t_slug]) ?>" class="back">← <?= $this->helper->translate('Back to publications list') ?></a> </article> <?php } ?> <?php if (($publicationResult->p->getTypeSlug() == 'locations')) { ?> <section class="parallax-window" data-parallax="scroll" data-image-src="<?= $this->url->path() ?><?= $publicationResult->p->banner_src ?>" data-natural-width="1400" data-natural-height="470"> <div class="parallax-content-1"> <div class="animated fadeInDown"> <h1><?= $publicationResult->title ?></h1> <p>Hãy khám phá việt nam qua những địa điểm phượt vô cùng thú vị, thơ mộng và hùng vĩ.</p> </div> </div> </section><!-- End section --> <style> .slider-pro { position: relative; margin: 0 auto; -moz-box-sizing: content-box; box-sizing: content-box } .sp-slides-container { position: relative } .sp-mask { position: relative; overflow: hidden } .sp-slides { position: relative; -webkit-backface-visibility: hidden; -webkit-perspective: 1000 } .sp-slide { position: absolute } .sp-image-container { overflow: hidden } .sp-image { position: relative; display: block; border: none } .sp-no-js { overflow: hidden; max-width: 100% } .sp-thumbnails-container { position: relative; overflow: hidden } .sp-bottom-thumbnails, .sp-top-thumbnails { left: 0; margin: 0 auto } .sp-top-thumbnails { position: absolute; top: 0; margin-bottom: 4px } .sp-bottom-thumbnails { margin-top: 4px } .sp-left-thumbnails, .sp-right-thumbnails { position: absolute; top: 0 } .sp-right-thumbnails { right: 0; margin-left: 4px } .sp-left-thumbnails { left: 0; margin-right: 4px } .sp-thumbnails { position: relative } .sp-thumbnail { border: none } .sp-thumbnail-container { position: relative; display: block; overflow: hidden; float: left; -moz-box-sizing: border-box; box-sizing: border-box } .sp-bottom-thumbnails .sp-thumbnail-container, .sp-top-thumbnails .sp-thumbnail-container { margin-left: 2px; margin-right: 2px } .sp-bottom-thumbnails .sp-thumbnail-container:first-child, .sp-top-thumbnails .sp-thumbnail-container:first-child { margin-left: 0 } .sp-bottom-thumbnails .sp-thumbnail-container:last-child, .sp-top-thumbnails .sp-thumbnail-container:last-child { margin-right: 0 } .sp-left-thumbnails .sp-thumbnail-container, .sp-right-thumbnails .sp-thumbnail-container { margin-top: 2px; margin-bottom: 2px } .sp-left-thumbnails .sp-thumbnail-container:first-child, .sp-right-thumbnails .sp-thumbnail-container:first-child { margin-top: 0 } .sp-left-thumbnails .sp-thumbnail-container:last-child, .sp-right-thumbnails .sp-thumbnail-container:last-child { margin-bottom: 0 } .sp-right-thumbnails.sp-has-pointer { margin-left: -13px } .sp-right-thumbnails.sp-has-pointer .sp-thumbnail { position: absolute; left: 18px; margin-left: 0 !important } .sp-right-thumbnails.sp-has-pointer .sp-selected-thumbnail:before { content: ''; position: absolute; height: 100%; border-left: 5px solid red; left: 0; top: 0; margin-left: 13px } .sp-right-thumbnails.sp-has-pointer .sp-selected-thumbnail:after { content: ''; position: absolute; width: 0; height: 0; left: 0; top: 50%; margin-top: -8px; border-right: 13px solid red; border-top: 8px solid transparent; border-bottom: 8px solid transparent } .sp-left-thumbnails.sp-has-pointer { margin-right: -13px } .sp-left-thumbnails.sp-has-pointer .sp-thumbnail { position: absolute; right: 18px } .sp-left-thumbnails.sp-has-pointer .sp-selected-thumbnail:before { content: ''; position: absolute; height: 100%; border-left: 5px solid red; right: 0; top: 0; margin-right: 13px } .sp-left-thumbnails.sp-has-pointer .sp-selected-thumbnail:after { content: ''; position: absolute; width: 0; height: 0; right: 0; top: 50%; margin-top: -8px; border-left: 13px solid red; border-top: 8px solid transparent; border-bottom: 8px solid transparent } .sp-bottom-thumbnails.sp-has-pointer { margin-top: -13px } .sp-bottom-thumbnails.sp-has-pointer .sp-thumbnail { position: absolute; top: 18px; margin-top: 0 !important } .sp-bottom-thumbnails.sp-has-pointer .sp-selected-thumbnail:before { content: ''; position: absolute; width: 100%; border-bottom: 5px solid red; top: 0; margin-top: 13px } .sp-bottom-thumbnails.sp-has-pointer .sp-selected-thumbnail:after { content: ''; position: absolute; width: 0; height: 0; left: 50%; top: 0; margin-left: -8px; border-bottom: 13px solid red; border-left: 8px solid transparent; border-right: 8px solid transparent } .sp-top-thumbnails.sp-has-pointer { margin-bottom: -13px } .sp-top-thumbnails.sp-has-pointer .sp-thumbnail { position: absolute; bottom: 18px } .sp-top-thumbnails.sp-has-pointer .sp-selected-thumbnail:before { content: ''; position: absolute; width: 100%; border-bottom: 5px solid red; bottom: 0; margin-bottom: 13px } .sp-top-thumbnails.sp-has-pointer .sp-selected-thumbnail:after { content: ''; position: absolute; width: 0; height: 0; left: 50%; bottom: 0; margin-left: -8px; border-top: 13px solid red; border-left: 8px solid transparent; border-right: 8px solid transparent } .sp-layer { position: absolute; margin: 0; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; -webkit-font-smoothing: subpixel-antialiased; -webkit-backface-visibility: hidden } .sp-black { color: #FFF; background: #000; background: rgba(0, 0, 0, .7) } .sp-white { color: #000; background: #fff; background: rgba(255, 255, 255, .7) } .sp-rounded { border-radius: 10px } .sp-padding { padding: 10px } .sp-grab { cursor: url(images/openhand.cur), move } .sp-grabbing { cursor: url(images/closedhand.cur), move } .sp-selectable { cursor: default } .sp-caption-container { text-align: center; margin-top: 10px } .sp-full-screen { margin: 0 !important; background-color: #000 } .sp-full-screen-button { position: absolute; top: 5px; right: 10px; font-size: 30px; line-height: 1; cursor: pointer; -webkit-transform: rotate(45deg); -ms-transform: rotate(45deg); transform: rotate(45deg) } .sp-full-screen-button:before { content: '\2195' } .sp-fade-full-screen { opacity: 0; -webkit-transition: opacity .5s; transition: opacity .5s } .slider-pro:hover .sp-fade-full-screen { opacity: 1 } .sp-buttons { position: relative; width: 100%; text-align: center; padding-top: 10px } .sp-button { width: 10px; height: 10px; border: 2px solid #000; border-radius: 50%; margin: 4px; display: inline-block; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; cursor: pointer } .sp-selected-button { background-color: #000 } @media only screen and (min-width: 768px) and (max-width: 1024px) { .sp-button { width: 14px; height: 14px } } @media only screen and (min-width: 568px) and (max-width: 768px) { .sp-button { width: 16px; height: 16px } } @media only screen and (min-width: 320px) and (max-width: 568px) { .sp-button { width: 18px; height: 18px } } .sp-arrows { position: absolute } .sp-fade-arrows { opacity: 0; -webkit-transition: opacity .5s; transition: opacity .5s } .sp-slides-container:hover .sp-fade-arrows { opacity: 1 } .sp-horizontal .sp-arrows { width: 100%; left: 0; top: 50%; margin-top: -15px } .sp-vertical .sp-arrows { height: 100%; left: 50%; top: 0; margin-left: -10px } .sp-arrow { position: absolute; display: block; width: 20px; height: 30px; cursor: pointer } .sp-vertical .sp-arrow { -webkit-transform: rotate(90deg); -ms-transform: rotate(90deg); transform: rotate(90deg) } .sp-horizontal .sp-previous-arrow { left: 20px } .sp-horizontal .sp-next-arrow { right: 20px } .sp-vertical .sp-previous-arrow { top: 20px } .sp-vertical .sp-next-arrow { bottom: 20px } .sp-next-arrow:after, .sp-next-arrow:before, .sp-previous-arrow:after, .sp-previous-arrow:before { content: ''; position: absolute; width: 50%; height: 50%; background-color: #FFF } .sp-previous-arrow:before { left: 30%; top: 0; -webkit-transform: skew(145deg, 0deg); -ms-transform: skew(145deg, 0deg); transform: skew(145deg, 0deg) } .sp-previous-arrow:after { left: 30%; top: 50%; -webkit-transform: skew(-145deg, 0deg); -ms-transform: skew(-145deg, 0deg); transform: skew(-145deg, 0deg) } .sp-next-arrow:before { right: 30%; top: 0; -webkit-transform: skew(35deg, 0deg); -ms-transform: skew(35deg, 0deg); transform: skew(35deg, 0deg) } .sp-next-arrow:after { right: 30%; top: 50%; -webkit-transform: skew(-35deg, 0deg); -ms-transform: skew(-35deg, 0deg); transform: skew(-35deg, 0deg) } .ie7 .sp-arrow, .ie8 .sp-arrow { width: 0; height: 0 } .ie7 .sp-arrow:after, .ie7 .sp-arrow:before, .ie8 .sp-arrow:after, .ie8 .sp-arrow:before { content: none } .ie7.sp-horizontal .sp-previous-arrow, .ie8.sp-horizontal .sp-previous-arrow { border-right: 20px solid #FFF; border-top: 20px solid transparent; border-bottom: 20px solid transparent } .ie7.sp-horizontal .sp-next-arrow, .ie8.sp-horizontal .sp-next-arrow { border-left: 20px solid #FFF; border-top: 20px solid transparent; border-bottom: 20px solid transparent } .ie7.sp-vertical .sp-previous-arrow, .ie8.sp-vertical .sp-previous-arrow { border-bottom: 20px solid #FFF; border-left: 20px solid transparent; border-right: 20px solid transparent } .ie7.sp-vertical .sp-next-arrow, .ie8.sp-vertical .sp-next-arrow { border-top: 20px solid #FFF; border-left: 20px solid transparent; border-right: 20px solid transparent } .sp-thumbnail-arrows { position: absolute } .sp-fade-thumbnail-arrows { opacity: 0; -webkit-transition: opacity .5s; transition: opacity .5s } .sp-thumbnails-container:hover .sp-fade-thumbnail-arrows { opacity: 1 } .sp-bottom-thumbnails .sp-thumbnail-arrows, .sp-top-thumbnails .sp-thumbnail-arrows { width: 100%; top: 50%; left: 0; margin-top: -12px } .sp-left-thumbnails .sp-thumbnail-arrows, .sp-right-thumbnails .sp-thumbnail-arrows { height: 100%; top: 0; left: 50%; margin-left: -7px } .sp-thumbnail-arrow { position: absolute; display: block; width: 15px; height: 25px; cursor: pointer } .sp-left-thumbnails .sp-thumbnail-arrows .sp-thumbnail-arrow, .sp-right-thumbnails .sp-thumbnail-arrows .sp-thumbnail-arrow { -webkit-transform: rotate(90deg); -ms-transform: rotate(90deg); transform: rotate(90deg) } .sp-bottom-thumbnails .sp-previous-thumbnail-arrow, .sp-top-thumbnails .sp-previous-thumbnail-arrow { left: 0 } .sp-bottom-thumbnails .sp-next-thumbnail-arrow, .sp-top-thumbnails .sp-next-thumbnail-arrow { right: 0 } .sp-left-thumbnails .sp-previous-thumbnail-arrow, .sp-right-thumbnails .sp-previous-thumbnail-arrow { top: 0 } .sp-left-thumbnails .sp-next-thumbnail-arrow, .sp-right-thumbnails .sp-next-thumbnail-arrow { bottom: 0 } .sp-next-thumbnail-arrow:after, .sp-next-thumbnail-arrow:before, .sp-previous-thumbnail-arrow:after, .sp-previous-thumbnail-arrow:before { content: ''; position: absolute; width: 50%; height: 50%; background-color: #FFF } .sp-previous-thumbnail-arrow:before { left: 30%; top: 0; -webkit-transform: skew(145deg, 0deg); -ms-transform: skew(145deg, 0deg); transform: skew(145deg, 0deg) } .sp-previous-thumbnail-arrow:after { left: 30%; top: 50%; -webkit-transform: skew(-145deg, 0deg); -ms-transform: skew(-145deg, 0deg); transform: skew(-145deg, 0deg) } .sp-next-thumbnail-arrow:before { right: 30%; top: 0; -webkit-transform: skew(35deg, 0deg); -ms-transform: skew(35deg, 0deg); transform: skew(35deg, 0deg) } .sp-next-thumbnail-arrow:after { right: 30%; top: 50%; -webkit-transform: skew(-35deg, 0deg); -ms-transform: skew(-35deg, 0deg); transform: skew(-35deg, 0deg) } .ie7 .sp-thumbnail-arrow, .ie8 .sp-thumbnail-arrow { width: 0; height: 0 } .ie7 .sp-thumbnail-arrow:after, .ie7 .sp-thumbnail-arrow:before, .ie8 .sp-thumbnail-arrow:after, .ie8 .sp-thumbnail-arrow:before { content: none } .ie7 .sp-bottom-thumbnails .sp-previous-thumbnail-arrow, .ie7 .sp-top-thumbnails .sp-previous-thumbnail-arrow, .ie8 .sp-bottom-thumbnails .sp-previous-thumbnail-arrow, .ie8 .sp-top-thumbnails .sp-previous-thumbnail-arrow { border-right: 12px solid #FFF; border-top: 12px solid transparent; border-bottom: 12px solid transparent } .ie7 .sp-bottom-thumbnails .sp-next-thumbnail-arrow, .ie7 .sp-top-thumbnails .sp-next-thumbnail-arrow, .ie8 .sp-bottom-thumbnails .sp-next-thumbnail-arrow, .ie8 .sp-top-thumbnails .sp-next-thumbnail-arrow { border-left: 12px solid #FFF; border-top: 12px solid transparent; border-bottom: 12px solid transparent } .ie7 .sp-left-thumbnails .sp-previous-thumbnail-arrow, .ie7 .sp-right-thumbnails .sp-previous-thumbnail-arrow, .ie8 .sp-left-thumbnails .sp-previous-thumbnail-arrow, .ie8 .sp-right-thumbnails .sp-previous-thumbnail-arrow { border-bottom: 12px solid #FFF; border-left: 12px solid transparent; border-right: 12px solid transparent } .ie7 .sp-left-thumbnails .sp-next-thumbnail-arrow, .ie7 .sp-right-thumbnails .sp-next-thumbnail-arrow, .ie8 .sp-left-thumbnails .sp-next-thumbnail-arrow, .ie8 .sp-right-thumbnails .sp-next-thumbnail-arrow { border-top: 12px solid #FFF; border-left: 12px solid transparent; border-right: 12px solid transparent } a.sp-video { text-decoration: none } a.sp-video img { -webkit-backface-visibility: hidden; border: none } a.sp-video:after { content: '\25B6'; position: absolute; width: 45px; padding-left: 5px; height: 50px; border: 2px solid #FFF; text-align: center; font-size: 30px; border-radius: 30px; top: 0; color: #FFF; bottom: 0; left: 0; right: 0; background-color: rgba(0, 0, 0, .2); margin: auto; line-height: 52px } .slider-pro img.sp-image, .slider-pro img.sp-thumbnail { max-width: none; max-height: none; border: none !important; border-radius: 0 !important; padding: 0 !important; -webkit-box-shadow: none !important; -mox-box-shadow: none !important; box-shadow: none !important; transition: none; -moz-transition: none; -webkit-transition: none; -o-transition: none } .slider-pro a { position: static; transition: none !important; -moz-transition: none !important; -webkit-transition: none !important; -o-transition: none !important } .slider-pro canvas, .slider-pro embed, .slider-pro iframe, .slider-pro object, .slider-pro video { max-width: none; max-height: none } .slider-pro p.sp-layer { font-size: 14px; line-height: 1.4; margin: 0 } .slider-pro h1.sp-layer { font-size: 32px; line-height: 1.4; margin: 0 } .slider-pro h2.sp-layer { font-size: 24px; line-height: 1.4; margin: 0 } .slider-pro h3.sp-layer { font-size: 19px; line-height: 1.4; margin: 0 } .slider-pro h4.sp-layer { font-size: 16px; line-height: 1.4; margin: 0 } .slider-pro h5.sp-layer { font-size: 13px; line-height: 1.4; margin: 0 } .slider-pro h6.sp-layer { font-size: 11px; line-height: 1.4; margin: 0 } .slider-pro img.sp-layer { border: none } </style> <?php $slide_ = explode("\n",$slide_img); ?> <div class="container margin_60"> <div0 class="row"> <div class="col-md-8" id="single_tour_desc"> <p class="visible-sm visible-xs"><a class="btn_map" data-toggle="collapse" href="#collapseMap" aria-expanded="false" aria-controls="collapseMap" data-text-swap="Hide map" data-text-original="View on map">View on map</a></p><!-- Map button for tablets/mobiles --> <div id="Img_carousel" class="slider-pro"> <div class="sp-slides"> <?php foreach($slide_ as $sl) { ?> <div class="sp-slide"> <img alt="Image" class="sp-image" src="css/images/blank.gif" data-src="/<?php echo $sl ?>" data-small="/<?php echo $sl ?>" data-medium="/<?php echo $sl ?>" data-large="/<?php echo $sl ?>" data-retina="/<?php echo $sl ?>"> </div> <?php } ?> </div> <div class="sp-thumbnails"> <?php foreach($slide_ as $sl) { echo '<img alt="Image" class="sp-thumbnail" src="/'.$sl.'">'; } ?> </div> </div> <hr> <div class="row"> <div class="col-md-12"> <?= $publicationResult->text ?> </div> <article id="content" class="publication clearfix" style="display: none;"> <?php if ($this->helper->isAdminSession()) { ?> <p style="font-weight: bold;font-size:120%;"> <a class="noajax" href="<?= $this->url->get() ?>publication/admin/edit/<?= $publicationResult->p->getId() ?>?lang=<?= constant('LANG') ?>"><?= $this->helper->at('Edit publication') ?></a> </p> <?php } ?> <h1><?= $publicationResult->title ?></h1> <?php if ($publicationResult->p->getTypeDisplayDate()) { ?> <section class="date"><?= $publicationResult->p->getDate('d.m.Y') ?></section> <?php } ?> <?php if ($publicationResult->p->preview_inner) { ?> <?php $image = $this->helper->image(['id' => $publicationResult->p->getId(), 'type' => 'publication', 'width' => 300, 'strategy' => 'w']); ?> <div class="image inner"> <?= $image->imageHTML() ?> </div> <?php } ?> <?= $publicationResult->text ?> <a href="<?= $this->helper->langUrl(['for' => 'publications', 'type' => $publicationResult->t_slug]) ?>" class="back">← <?= $this->helper->translate('Back to publications list') ?></a> </article> <div style="clear:both"></div> <div class="row"> <h3 style="margin: 25px"> Khám phá <a href="<?= $this->url->path() ?>locations?loc=<?php echo $parent;?>"><span><?= $totalLocation ?></span></a> địa điểm ở <a href="<?= $this->url->path() ?>locations?loc=<?php echo $parent;?>"><span style="color: #74d62f"><?php echo $locdt[$parent];?></span></a></h3> <?php foreach($des_more as $loc) : if ($loc->preview_src) { $preview_src = $loc->preview_src; } else { $slide_ = explode("\n", $loc->slide_img); $preview_src = @reset($slide_); } ?> <div class="col-md-4 col-sm-6 wow zoomIn" data-wow-delay="0.1s"> <div class="tour_container"> <div class="ribbon_3 popular" style="display: none;"><span>Popular</span></div> <div class="img_container"> <a href='<?= $this->url->path() ?><?php echo "locations/".$loc->slug.".html";?>' title="<?php echo $loc->preview_src;?>"> <img src="<?= $this->url->path() ?><?= $preview_src ?>" class="img-responsive" alt="image"> <div class="short_info"> <i class="icon_set_1_icon-44"></i> <?php echo $locdt[$loc->des_parent];?><span class="price"><sup></sup></span> </div> </a> </div> <div class="tour_title"> <h3><strong style="font-size: 16px !important; text-transform: none !important;"><?php echo $loc->title;?></strong> </h3> <div class="rating"> <i class="icon-smile voted"></i><i class="icon-smile voted"></i><i class="icon-smile voted"></i><i class="icon-smile voted"></i><i class="icon-smile"></i><small><?php echo rand(100,1000) ?></small> </div><!-- end rating --> <div class="wishlist"> <a class="tooltip_flip tooltip-effect-1" href="javascript:void(0);">+<span class="tooltip-content-flip"><span class="tooltip-back">Add to wishlist</span></span></a> </div><!-- End wish list--> </div> </div><!-- End box tour --> </div><!-- End col-md-4 --> <?php endforeach; ?> </div> <div class="MapsNearestLocationDetail" data-latitude="<?= ($publicationResult->p->latitude ? $publicationResult->p->latitude : 0) ?>" data-longitude="<?= ($publicationResult->p->longitude ? $publicationResult->p->longitude : 0) ?>"> <div class="main_title"> <h3>Điểm <span>phượt</span> gần <span><?= $publicationResult->title ?></span></h3> </div> <div id="map" class="map"></div> </div> <div style="padding-top: 10px"> <div class="fb-like" data-href='<?php echo "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; ?>' data-layout="standard" data-action="like" data-size="small" data-show-faces="true" data-share="true"></div> <div style="width:100% !important;" class="fb-comments" data-href='<?php echo "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; ?>' data-numposts="5"></div> </div> </div><!-- End row --> </div><!--End single_tour_desc--> <aside class="col-md-4"> <p class="hidden-sm hidden-xs" style="display: none;"> <a class="btn_map" data-toggle="collapse" href="#collapseMap" aria-expanded="false" aria-controls="collapseMap" data-text-swap="Hide map" data-text-original="View on map">View on map</a> </p> <input type="text" id="y_rating" class="rating-loading" name="y_rating" value="<?php if (!(empty($rate))) { ?><?= $rate->num_rate ?><?php } else { ?>0<?php } ?>" > <div class="box_style_4 other_tours youvivu-location-box_style_4"> <?php $location_id = $publicationResult->p->id; ?> <?php $media = \Publication\Model\Helper\PublicationHelper::getAllMedia($location_id);?> <ul class=""> <li> <a data-object-id="<?= $publicationResult->p->id ?>" data-action="L" class="click-show-media" rel="nofollow" href="javascript:void(0)" data-title="Đã yêu thích"> <i class="icon_set_1_icon-82"></i>Đã yêu thích<span class="other_tours_price"> <strong> <?php if(!empty($media) && !empty($media["L"])) { echo $media['L']; }else{ echo '0'; } ?> </strong> </span> </a> </li> <li><a data-object-id="<?= $location_id ?>" data-action="W" class="click-show-media" rel="nofollow" href="javascript:void(0)" data-title="Đã đến đây"><i class=" icon_set_1_icon-30"></i>Đã đến đây <span class="other_tours_price"> <strong> <?php if(!empty($media) && !empty($media["W"])) { echo $media['W']; }else{ echo '0'; } ?> </strong></span> </a> </li> <li> <a data-object-id="<?= $location_id ?>" data-action="R" class="click-show-media" rel="nofollow" href="javascript:void(0)" data-title="Đã đánh giá"> <i class="icon_set_1_icon-81"></i>Đã đánh giá <span class="other_tours_price"> <strong> <?php if(!empty($media) && !empty($media["R"])) { echo $media['R']; }else{ echo '0'; } ?> </strong> </span> </a> </li> </ul> </div> <?php $userLikeMedia = \Publication\Model\Helper\PublicationHelper::getMediaByUserID($location_id, 'L') ?> <?php $liked = 'like'; ?> <?php $object_type_like = 1; ?> <?php $original_title_like = 'Yêu thích'; ?> <?php if (!empty($userLikeMedia)) { ?> <?php $liked = 'unlike'; ?> <?php $original_title_like = 'Bỏ thích'; ?> <?php $object_type_like = 0; ?> <?php } ?> <?php $userWentMedia = \Publication\Model\Helper\PublicationHelper::getMediaByUserID($location_id, 'W') ?> <?php $wented = 'maskWent'; ?> <?php $object_type_went = 1; ?> <?php $original_title_went = 'Đánh dấu đã đến đây'; ?> <?php if (!empty($userWentMedia)) { ?> <?php $wented = 'maskUnWent'; ?> <?php $object_type_went = 0; ?> <?php $original_title_went = 'Bạn đã đánh dấu là đã đến đây'; ?> <?php } ?> <ul class="add_info youvivu-location-add_info"> <li> <a rel="<?= $liked ?>" data-object-type="<?= $object_type_like ?>" data-object-id="<?= $location_id ?>" href="javascript:void(0);" class="tooltip-1 youvivu-object-like" data-placement="top" title="" data-original-title="<?= $original_title_like ?>"> <i class="icon_set_1_icon-18"></i> </a> </li> <li> <a rel="<?= $wented ?>" data-object-type="<?= $object_type_went ?>" data-object-id="<?= $location_id ?>" href="javascript:void(0);" class="tooltip-1 youvivu-object-location-mask-went" data-placement="top" title="" data-original-title="<?= $original_title_went ?>"> <i class=" icon_set_1_icon-30"></i> </a> </li> <li> <a rel="addPlan" data-object-type="1" data-object-id="<?= $location_id ?>" href="javascript:void(0);" class="tooltip-1 youvivu-object-location-add-to-plan" data-placement="top" title="" data-original-title="Thêm vào kế hoạch đến đây"> <i class="icon_set_1_icon-83"></i></a> </li> <li> <a data-object-type="1" data-object-id="<?= $location_id ?>" href="/modal/map?locationId=<?= $location_id ?>" class="tooltip-1 ajax-maps-popup" data-placement="top" title="" data-original-title="Xem trên bản đồ"> <i class="icon_set_1_icon-41"></i></a> </li> </ul> <div class="box_style_4"> <i class="icon_set_1_icon-90"></i> <h4><span>Book</span> by phone</h4> <a href="tel://004542344599" class="phone">+84 983 035 435</a> <small>Monday to Friday 9.00am - 7.30pm</small> </div> <div style="display: none;"> <?php foreach($cul as $cu) { ?> <div id="cul_<?php echo $cu->id ?>" style="display: none;"><?php echo ($cu->text) ?></div> <?php } ?> </div> <div class="box_style_cat youviu-box-culture-common youviu-box-culture-destination"><h3 style="text-align: center">Văn hóa & con người</h3> <ul id="cat_nav" class="listBlogInLocation"> <?php foreach($cul as $cu) { ?> <li><a class="youviu-culture-popup-detail" rel="nofollow" data-title="<?php echo $cu->title ?>" data-href="showcul(<?php echo $cu->id ?>)" onclick="showcul(<?php echo $cu->id ?>)" href="javascript:void(0)"> <img style="width: 54px;height: 54px;" class="lazy" alt="<?php echo $cu->title ?>" data-original="/<?php echo $cu->preview_src ?>" src="/assets/ba871a56/img/loading.gif"><span> <?php echo $cu->title ?><br><div class="rating"><i class="icon-star voted"></i><i class="icon-star voted"></i><i class="icon-star voted"></i><i class="icon-star voted"></i><i class="icon-star-empty"></i></div><br><i class="icon-calendar-empty"></i> Đăng ngày 01/01/2017 </span> <div style="clear:both"></div> </a></li> <?php } ?> <div id="youviu-modal-culture-detail" class="white-popup mfp-hide"> <div class="body"></div> </div> </ul> </div> </aside> </div><!--End row --> </div><!--End container --> <!-- Carousel --> <script src="<?= $this->url->path() ?>static/js/jquery.sliderPro.min.js"></script> <script src="<?= $this->url->path() ?>static/js/jquery.magnific-popup.js"></script> <script type="text/javascript"> $(document).ready(function ($) { $('#Img_carousel').sliderPro({ width: 960, height: 500, fade: true, arrows: true, buttons: false, fullScreen: false, smallSize: 500, startSlide: 0, mediumSize: 1000, largeSize: 3000, thumbnailArrows: true, autoplay: false }); }); </script> <script src="<?= $this->url->path() ?>static/js/owl.carousel.min.js"></script> <script> $(document).ready(function () { $(".carousel").owlCarousel({ items: 4, itemsDesktop: [1199, 3], itemsDesktopSmall: [979, 3] }); }); </script> <?php } ?> <script> $("img.lazy").each(function () { $(this).attr("src", $(this).attr("data-original")); $(this).removeAttr("data-original"); }); $(document).ready(function () { $(".mfp-close").click(function(){ $(".mfp-wrap").hide(); $(".mfp-bg").hide(); }); $(".mfp-content").click(function(){ // alert(1); }); $(".mfp-bg").hide(); $(".mfp-content").click(function(){ // alert(1); }); }); function showcul(id){ $("#cul_content").html($("#cul_"+id).html()); $(".mfp-wrap").show(); $(".mfp-bg").show(); } </script> <script src="https://maps.googleapis.com/maps/api/js?libraries=places&key=<?= $map_key ?>"></script> <script> (function (A) { if (!Array.prototype.forEach) A.forEach = A.forEach || function (action, that) { for (var i = 0, l = this.length; i < l; i++) if (i in this) action.call(that, this[i], i, this); }; })(Array.prototype); jQuery(document).ready(function () { jQuery('#y_rating').on('rating.change', function (event, value, caption) { rating(value, <?= $publicationResult->p->id ?>, 'change') }); jQuery('#y_rating').on('rating.clear', function (event) { rating(0, <?= $publicationResult->p->id ?>, 'clear') }); }); </script> <script src="<?= $this->url->path() ?>static/js/infoBox.js"></script> |
#4 | Phalcon\Mvc\View\Engine\Volt->render(/www/wiki.youvivu.com/public_html/app/modules/Publication/views/index/publication.volt, Array(10), true) |
#5 | Phalcon\Mvc\View->_engineRender(Array([.volt] => Object(Application\Mvc\View\Engine\Volt), [.phtml] => Object(Phalcon\Mvc\View\Engine\Php)), index/publication, true, true, null) |
#6 | Phalcon\Mvc\View->render(index, publication, Array([type] => locations, [slug] => hang-lang)) /www/wiki.youvivu.com/public_html/app/Bootstrap.php (349) <?php namespace YonaCMS; use Application\Cache\Manager as CacheManager; use Phalcon\Http\Response\Cookies; use Phalcon\UserPlugin\Auth\Auth; /** * Bootstrap * @copyright Copyright (c) 2011 - 2014 Aleksandr Torosh (http://wezoom.com.ua) * @author Aleksandr Torosh <webtorua@gmail.com> */ class Bootstrap { public function run() { $di = new \Phalcon\DI\FactoryDefault(); // Config require_once APPLICATION_PATH . '/modules/Cms/Config.php'; $config = \Cms\Config::get(); $di->set('config', $config); // Registry $registry = new \Phalcon\Registry(); $di->set('registry', $registry); // Loader $loader = new \Phalcon\Loader(); $loader->registerNamespaces($config->loader->namespaces->toArray()); $loader->registerDirs([APPLICATION_PATH . "/plugins/"]); $loader->registerFiles([APPLICATION_PATH . '/../vendor/autoload.php']); $loader->register(); // Database $db = new \Phalcon\Db\Adapter\Pdo\Mysql([ "host" => $config->database->host, "username" => $config->database->username, "password" => $config->database->password, "dbname" => $config->database->dbname, "charset" => $config->database->charset, ]); $di->set('db', $db); // View $this->initView($di); // URL $url = new \Phalcon\Mvc\Url(); $url->setBasePath($config->base_path); $url->setBaseUri($config->base_path); $di->set('url', $url); // Cache $this->initCache($di); // CMS $cmsModel = new \Cms\Model\Configuration(); $registry->cms = $cmsModel->getConfig(); // Отправляем в Registry // Application $application = new \Phalcon\Mvc\Application(); $application->registerModules($config->modules->toArray()); // Events Manager, Dispatcher $this->initEventManager($di); // Session $session = new \Phalcon\Session\Adapter\Files(); $session->start(); $di->set('session', $session); $di->set( "cookies", function () { $cookies = new Cookies(); $cookies->useEncryption(false); return $cookies; } ); $di->setShared( 'auth', function () { return new Auth(); } ); $acl = new \Application\Acl\DefaultAcl(); $di->set('acl', $acl); // JS Assets $this->initAssetsManager($di); // Flash helper $flash = new \Phalcon\Flash\Session([ 'error' => 'ui red inverted segment alert alert-danger', 'success' => 'ui green inverted segment alert alert-success', 'notice' => 'ui blue inverted segment alert alert-info', 'warning' => 'ui orange inverted segment alert alert-warning', ]); $di->set('flash', $flash); $di->set('helper', new \Application\Mvc\Helper()); // Routing $this->initRouting($application, $di); $application->setDI($di); // Main dispatching process $response = $this->dispatch($di); $response->send(); } private function initRouting($application, $di) { $router = new \Application\Mvc\Router\DefaultRouter(); $router->setDi($di); foreach ($application->getModules() as $module) { $routesClassName = str_replace('Module', 'Routes', $module['className']); if (class_exists($routesClassName)) { $routesClass = new $routesClassName(); $router = $routesClass->init($router); } $initClassName = str_replace('Module', 'Init', $module['className']); if (class_exists($initClassName)) { new $initClassName(); } } $di->set('router', $router); } private function initAssetsManager($di) { $config = $di->get('config'); $assetsManager = new \Application\Assets\Manager(); $js_collection = $assetsManager->collection('js') ->setLocal(true) ->addFilter(new \Phalcon\Assets\Filters\Jsmin()) ->setTargetPath(ROOT . '/assets/js.js') ->setTargetUri('assets/js.js') ->join(true); if ($config->assets->js) { foreach ($config->assets->js as $js) { $js_collection->addJs(ROOT . '/' . $js); } } // Admin JS Assets $assetsManager->collection('modules-admin-js') ->setLocal(true) ->addFilter(new \Phalcon\Assets\Filters\Jsmin()) ->setTargetPath(ROOT . '/assets/modules-admin.js') ->setTargetUri('assets/modules-admin.js') ->join(true); // Admin LESS Assets $assetsManager->collection('modules-admin-less') ->setLocal(true) ->addFilter(new \Application\Assets\Filter\Less()) ->setTargetPath(ROOT . '/assets/modules-admin.less') ->setTargetUri('assets/modules-admin.less') ->join(true) ->addCss(APPLICATION_PATH . '/modules/Admin/assets/admin.less'); $di->set('assets', $assetsManager); } private function initEventManager($di) { $eventsManager = new \Phalcon\Events\Manager(); $dispatcher = new \Phalcon\Mvc\Dispatcher(); $eventsManager->attach("dispatch:beforeDispatchLoop", function ($event, $dispatcher) use ($di) { new \YonaCMS\Plugin\CheckPoint($di->get('request')); new \YonaCMS\Plugin\Localization($dispatcher); new \YonaCMS\Plugin\AdminLocalization($di->get('config')); new \YonaCMS\Plugin\Acl($di->get('acl'), $dispatcher, $di->get('view')); new \YonaCMS\Plugin\MobileDetect($di->get('session'), $di->get('view'), $di->get('request')); }); $eventsManager->attach("dispatch:afterDispatchLoop", function ($event, $dispatcher) use ($di) { new \Seo\Plugin\SeoManager($dispatcher, $di->get('request'), $di->get('router'), $di->get('view')); new \YonaCMS\Plugin\Title($di); }); // Profiler $registry = $di->get('registry'); if ($registry->cms['PROFILER']) { $profiler = new \Phalcon\Db\Profiler(); $di->set('profiler', $profiler); $eventsManager->attach('db', function ($event, $db) use ($profiler) { if ($event->getType() == 'beforeQuery') { $profiler->startProfile($db->getSQLStatement()); } if ($event->getType() == 'afterQuery') { $profiler->stopProfile(); } }); } $db = $di->get('db'); $db->setEventsManager($eventsManager); $dispatcher->setEventsManager($eventsManager); $di->set('dispatcher', $dispatcher); } private function initView($di) { $view = new \Phalcon\Mvc\View(); define('MAIN_VIEW_PATH', '../../../views/'); $view->setMainView(MAIN_VIEW_PATH . 'main'); $view->setLayoutsDir(MAIN_VIEW_PATH . '/layouts/'); $view->setLayout('main'); $view->setPartialsDir(MAIN_VIEW_PATH . '/partials/'); // Volt $volt = new \Application\Mvc\View\Engine\Volt($view, $di); $volt->setOptions(['compiledPath' => APPLICATION_PATH . '/../data/cache/volt/']); $volt->initCompiler(); $phtml = new \Phalcon\Mvc\View\Engine\Php($view, $di); $viewEngines = [ ".volt" => $volt, ".phtml" => $phtml, ]; $view->registerEngines($viewEngines); $ajax = $di->get('request')->getQuery('_ajax'); if ($ajax) { $view->setRenderLevel(\Phalcon\Mvc\View::LEVEL_LAYOUT); } $di->set('view', $view); return $view; } private function initCache($di) { $config = $di->get('config'); $cacheFrontend = new \Phalcon\Cache\Frontend\Data([ "lifetime" => 60, "prefix" => HOST_HASH, ]); $cache = null; switch ($config->cache) { case 'file': $cache = new \Phalcon\Cache\Backend\File($cacheFrontend, [ "cacheDir" => APPLICATION_PATH . "/../data/cache/backend/" ]); break; case 'memcache': $cache = new \Phalcon\Cache\Backend\Memcache( $cacheFrontend, [ "host" => $config->memcache->host, "port" => $config->memcache->port, ]); break; case 'memcached': $cache = new \Phalcon\Cache\Backend\Libmemcached( $cacheFrontend, [ "host" => $config->memcached->host, "port" => $config->memcached->port, ]); break; } $di->set('cache', $cache, true); $di->set('modelsCache', $cache, true); \Application\Widget\Proxy::$cache = $cache; // Modules Widget System $modelsMetadata = new \Phalcon\Mvc\Model\Metadata\Memory(); $di->set('modelsMetadata', $modelsMetadata); $di->set('cacheManager', new CacheManager()); } private function dispatch($di) { $router = $di['router']; $router->handle(); $view = $di['view']; $dispatcher = $di['dispatcher']; $response = $di['response']; $dispatcher->setModuleName($router->getModuleName()); $dispatcher->setControllerName($router->getControllerName()); $dispatcher->setActionName($router->getActionName()); $dispatcher->setParams($router->getParams()); $moduleName = \Application\Utils\ModuleName::camelize($router->getModuleName()); $ModuleClassName = $moduleName . '\Module'; if (class_exists($ModuleClassName)) { $module = new $ModuleClassName; $module->registerAutoloaders(); $module->registerServices($di); } $view->start(); $registry = $di['registry']; if ($registry->cms['DEBUG_MODE']) { $debug = new \Phalcon\Debug(); $debug->listen(); $dispatcher->dispatch(); } else { try { $dispatcher->dispatch(); } catch (\Phalcon\Exception $e) { // Errors catching $view->setViewsDir(__DIR__ . '/modules/Index/views/'); $view->setPartialsDir(''); $view->e = $e; if ($e instanceof \Phalcon\Mvc\Dispatcher\Exception) { $response->setStatusCode(404, 'Not Found'); $view->partial('error/error404'); } else { $response->setStatusCode(503, 'Service Unavailable'); $view->partial('error/error503'); } return $response; } } $view->render( $dispatcher->getControllerName(), $dispatcher->getActionName(), $dispatcher->getParams() ); $view->finish(); // AJAX $request = $di['request']; $_ajax = $request->getQuery('_ajax'); if ($_ajax) { $contents = $view->getContent(); $return = new \stdClass(); $return->html = $contents; $return->title = $di->get('helper')->title()->get(); $return->success = true; if ($view->bodyClass) { $return->bodyClass = $view->bodyClass; } $headers = $response->getHeaders()->toArray(); if (isset($headers[404]) || isset($headers[503])) { $return->success = false; } $response->setContentType('application/json', 'UTF-8'); $response->setContent(json_encode($return)); } else { $response->setContent($view->getContent()); } return $response; } } |
#7 | YonaCMS\Bootstrap->dispatch(Object(Phalcon\Di\FactoryDefault)) /www/wiki.youvivu.com/public_html/app/Bootstrap.php (115) <?php namespace YonaCMS; use Application\Cache\Manager as CacheManager; use Phalcon\Http\Response\Cookies; use Phalcon\UserPlugin\Auth\Auth; /** * Bootstrap * @copyright Copyright (c) 2011 - 2014 Aleksandr Torosh (http://wezoom.com.ua) * @author Aleksandr Torosh <webtorua@gmail.com> */ class Bootstrap { public function run() { $di = new \Phalcon\DI\FactoryDefault(); // Config require_once APPLICATION_PATH . '/modules/Cms/Config.php'; $config = \Cms\Config::get(); $di->set('config', $config); // Registry $registry = new \Phalcon\Registry(); $di->set('registry', $registry); // Loader $loader = new \Phalcon\Loader(); $loader->registerNamespaces($config->loader->namespaces->toArray()); $loader->registerDirs([APPLICATION_PATH . "/plugins/"]); $loader->registerFiles([APPLICATION_PATH . '/../vendor/autoload.php']); $loader->register(); // Database $db = new \Phalcon\Db\Adapter\Pdo\Mysql([ "host" => $config->database->host, "username" => $config->database->username, "password" => $config->database->password, "dbname" => $config->database->dbname, "charset" => $config->database->charset, ]); $di->set('db', $db); // View $this->initView($di); // URL $url = new \Phalcon\Mvc\Url(); $url->setBasePath($config->base_path); $url->setBaseUri($config->base_path); $di->set('url', $url); // Cache $this->initCache($di); // CMS $cmsModel = new \Cms\Model\Configuration(); $registry->cms = $cmsModel->getConfig(); // Отправляем в Registry // Application $application = new \Phalcon\Mvc\Application(); $application->registerModules($config->modules->toArray()); // Events Manager, Dispatcher $this->initEventManager($di); // Session $session = new \Phalcon\Session\Adapter\Files(); $session->start(); $di->set('session', $session); $di->set( "cookies", function () { $cookies = new Cookies(); $cookies->useEncryption(false); return $cookies; } ); $di->setShared( 'auth', function () { return new Auth(); } ); $acl = new \Application\Acl\DefaultAcl(); $di->set('acl', $acl); // JS Assets $this->initAssetsManager($di); // Flash helper $flash = new \Phalcon\Flash\Session([ 'error' => 'ui red inverted segment alert alert-danger', 'success' => 'ui green inverted segment alert alert-success', 'notice' => 'ui blue inverted segment alert alert-info', 'warning' => 'ui orange inverted segment alert alert-warning', ]); $di->set('flash', $flash); $di->set('helper', new \Application\Mvc\Helper()); // Routing $this->initRouting($application, $di); $application->setDI($di); // Main dispatching process $response = $this->dispatch($di); $response->send(); } private function initRouting($application, $di) { $router = new \Application\Mvc\Router\DefaultRouter(); $router->setDi($di); foreach ($application->getModules() as $module) { $routesClassName = str_replace('Module', 'Routes', $module['className']); if (class_exists($routesClassName)) { $routesClass = new $routesClassName(); $router = $routesClass->init($router); } $initClassName = str_replace('Module', 'Init', $module['className']); if (class_exists($initClassName)) { new $initClassName(); } } $di->set('router', $router); } private function initAssetsManager($di) { $config = $di->get('config'); $assetsManager = new \Application\Assets\Manager(); $js_collection = $assetsManager->collection('js') ->setLocal(true) ->addFilter(new \Phalcon\Assets\Filters\Jsmin()) ->setTargetPath(ROOT . '/assets/js.js') ->setTargetUri('assets/js.js') ->join(true); if ($config->assets->js) { foreach ($config->assets->js as $js) { $js_collection->addJs(ROOT . '/' . $js); } } // Admin JS Assets $assetsManager->collection('modules-admin-js') ->setLocal(true) ->addFilter(new \Phalcon\Assets\Filters\Jsmin()) ->setTargetPath(ROOT . '/assets/modules-admin.js') ->setTargetUri('assets/modules-admin.js') ->join(true); // Admin LESS Assets $assetsManager->collection('modules-admin-less') ->setLocal(true) ->addFilter(new \Application\Assets\Filter\Less()) ->setTargetPath(ROOT . '/assets/modules-admin.less') ->setTargetUri('assets/modules-admin.less') ->join(true) ->addCss(APPLICATION_PATH . '/modules/Admin/assets/admin.less'); $di->set('assets', $assetsManager); } private function initEventManager($di) { $eventsManager = new \Phalcon\Events\Manager(); $dispatcher = new \Phalcon\Mvc\Dispatcher(); $eventsManager->attach("dispatch:beforeDispatchLoop", function ($event, $dispatcher) use ($di) { new \YonaCMS\Plugin\CheckPoint($di->get('request')); new \YonaCMS\Plugin\Localization($dispatcher); new \YonaCMS\Plugin\AdminLocalization($di->get('config')); new \YonaCMS\Plugin\Acl($di->get('acl'), $dispatcher, $di->get('view')); new \YonaCMS\Plugin\MobileDetect($di->get('session'), $di->get('view'), $di->get('request')); }); $eventsManager->attach("dispatch:afterDispatchLoop", function ($event, $dispatcher) use ($di) { new \Seo\Plugin\SeoManager($dispatcher, $di->get('request'), $di->get('router'), $di->get('view')); new \YonaCMS\Plugin\Title($di); }); // Profiler $registry = $di->get('registry'); if ($registry->cms['PROFILER']) { $profiler = new \Phalcon\Db\Profiler(); $di->set('profiler', $profiler); $eventsManager->attach('db', function ($event, $db) use ($profiler) { if ($event->getType() == 'beforeQuery') { $profiler->startProfile($db->getSQLStatement()); } if ($event->getType() == 'afterQuery') { $profiler->stopProfile(); } }); } $db = $di->get('db'); $db->setEventsManager($eventsManager); $dispatcher->setEventsManager($eventsManager); $di->set('dispatcher', $dispatcher); } private function initView($di) { $view = new \Phalcon\Mvc\View(); define('MAIN_VIEW_PATH', '../../../views/'); $view->setMainView(MAIN_VIEW_PATH . 'main'); $view->setLayoutsDir(MAIN_VIEW_PATH . '/layouts/'); $view->setLayout('main'); $view->setPartialsDir(MAIN_VIEW_PATH . '/partials/'); // Volt $volt = new \Application\Mvc\View\Engine\Volt($view, $di); $volt->setOptions(['compiledPath' => APPLICATION_PATH . '/../data/cache/volt/']); $volt->initCompiler(); $phtml = new \Phalcon\Mvc\View\Engine\Php($view, $di); $viewEngines = [ ".volt" => $volt, ".phtml" => $phtml, ]; $view->registerEngines($viewEngines); $ajax = $di->get('request')->getQuery('_ajax'); if ($ajax) { $view->setRenderLevel(\Phalcon\Mvc\View::LEVEL_LAYOUT); } $di->set('view', $view); return $view; } private function initCache($di) { $config = $di->get('config'); $cacheFrontend = new \Phalcon\Cache\Frontend\Data([ "lifetime" => 60, "prefix" => HOST_HASH, ]); $cache = null; switch ($config->cache) { case 'file': $cache = new \Phalcon\Cache\Backend\File($cacheFrontend, [ "cacheDir" => APPLICATION_PATH . "/../data/cache/backend/" ]); break; case 'memcache': $cache = new \Phalcon\Cache\Backend\Memcache( $cacheFrontend, [ "host" => $config->memcache->host, "port" => $config->memcache->port, ]); break; case 'memcached': $cache = new \Phalcon\Cache\Backend\Libmemcached( $cacheFrontend, [ "host" => $config->memcached->host, "port" => $config->memcached->port, ]); break; } $di->set('cache', $cache, true); $di->set('modelsCache', $cache, true); \Application\Widget\Proxy::$cache = $cache; // Modules Widget System $modelsMetadata = new \Phalcon\Mvc\Model\Metadata\Memory(); $di->set('modelsMetadata', $modelsMetadata); $di->set('cacheManager', new CacheManager()); } private function dispatch($di) { $router = $di['router']; $router->handle(); $view = $di['view']; $dispatcher = $di['dispatcher']; $response = $di['response']; $dispatcher->setModuleName($router->getModuleName()); $dispatcher->setControllerName($router->getControllerName()); $dispatcher->setActionName($router->getActionName()); $dispatcher->setParams($router->getParams()); $moduleName = \Application\Utils\ModuleName::camelize($router->getModuleName()); $ModuleClassName = $moduleName . '\Module'; if (class_exists($ModuleClassName)) { $module = new $ModuleClassName; $module->registerAutoloaders(); $module->registerServices($di); } $view->start(); $registry = $di['registry']; if ($registry->cms['DEBUG_MODE']) { $debug = new \Phalcon\Debug(); $debug->listen(); $dispatcher->dispatch(); } else { try { $dispatcher->dispatch(); } catch (\Phalcon\Exception $e) { // Errors catching $view->setViewsDir(__DIR__ . '/modules/Index/views/'); $view->setPartialsDir(''); $view->e = $e; if ($e instanceof \Phalcon\Mvc\Dispatcher\Exception) { $response->setStatusCode(404, 'Not Found'); $view->partial('error/error404'); } else { $response->setStatusCode(503, 'Service Unavailable'); $view->partial('error/error503'); } return $response; } } $view->render( $dispatcher->getControllerName(), $dispatcher->getActionName(), $dispatcher->getParams() ); $view->finish(); // AJAX $request = $di['request']; $_ajax = $request->getQuery('_ajax'); if ($_ajax) { $contents = $view->getContent(); $return = new \stdClass(); $return->html = $contents; $return->title = $di->get('helper')->title()->get(); $return->success = true; if ($view->bodyClass) { $return->bodyClass = $view->bodyClass; } $headers = $response->getHeaders()->toArray(); if (isset($headers[404]) || isset($headers[503])) { $return->success = false; } $response->setContentType('application/json', 'UTF-8'); $response->setContent(json_encode($return)); } else { $response->setContent($view->getContent()); } return $response; } } |
#8 | YonaCMS\Bootstrap->run() /www/wiki.youvivu.com/public_html/public/index.php (20) <?php chdir(dirname(__DIR__)); define('ROOT', __DIR__); define('HOST_HASH', substr(md5($_SERVER['HTTP_HOST']), 0, 12)); if (isset($_SERVER['APPLICATION_ENV'])) { $applicationEnv = ($_SERVER['APPLICATION_ENV'] ? $_SERVER['APPLICATION_ENV'] : 'production'); } else { $applicationEnv = (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'); } define('APPLICATION_ENV', $applicationEnv); define('APPLICATION_PATH', __DIR__ . '/../app'); require_once APPLICATION_PATH . '/Bootstrap.php'; $bootstrap = new YonaCMS\Bootstrap(); $bootstrap->run(); |
Key | Value |
---|---|
_url | /locations/hang-lang.html |
Key | Value |
---|---|
TEMP | /tmp |
TMPDIR | /tmp |
TMP | /tmp |
PATH | /usr/local/bin:/usr/bin:/bin |
HOSTNAME | |
USER | nginx |
HOME | /var/lib/nginx |
FCGI_ROLE | RESPONDER |
QUERY_STRING | _url=/locations/hang-lang.html |
REQUEST_METHOD | GET |
CONTENT_TYPE | |
CONTENT_LENGTH | |
SCRIPT_NAME | /index.php |
REQUEST_URI | /locations/hang-lang.html |
DOCUMENT_URI | /index.php |
DOCUMENT_ROOT | /www/wiki.youvivu.com/public_html/public |
SERVER_PROTOCOL | HTTP/2.0 |
REQUEST_SCHEME | https |
HTTPS | on |
GATEWAY_INTERFACE | CGI/1.1 |
SERVER_SOFTWARE | nginx/1.20.1 |
REMOTE_ADDR | 52.14.110.171 |
REMOTE_PORT | 13534 |
SERVER_ADDR | 10.148.0.4 |
SERVER_PORT | 443 |
SERVER_NAME | wiki.youvivu.com |
REDIRECT_STATUS | 200 |
PATH_INFO | |
APPLICATION_ENV | production |
SCRIPT_FILENAME | /www/wiki.youvivu.com/public_html/public/index.php |
HTTP_HOST | wiki.youvivu.com |
HTTP_ACCEPT | */* |
HTTP_USER_AGENT | Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com) |
HTTP_ACCEPT_ENCODING | gzip, br, zstd, deflate |
HTTP_COOKIE | fikker-61vm-nk2N=MgPGRI6oXLV7DSLWJk4y6wNi63F1ZE0E |
PHP_SELF | |
REQUEST_TIME_FLOAT | 1732325296.2279 |
REQUEST_TIME | 1732325296 |
# | Path |
---|---|
0 | /www/wiki.youvivu.com/public_html/public/index.php |
1 | /www/wiki.youvivu.com/public_html/app/Bootstrap.php |
2 | /www/wiki.youvivu.com/public_html/app/modules/Cms/Config.php |
3 | /www/wiki.youvivu.com/public_html/app/config/environment/production.php |
4 | /www/wiki.youvivu.com/public_html/app/config/global.php |
5 | /www/wiki.youvivu.com/public_html/app/config/modules.php |
6 | /www/wiki.youvivu.com/public_html/app/modules/Application/Loader/Modules.php |
7 | /www/wiki.youvivu.com/public_html/vendor/autoload.php |
8 | /www/wiki.youvivu.com/public_html/vendor/composer/autoload_real.php |
9 | /www/wiki.youvivu.com/public_html/vendor/composer/ClassLoader.php |
10 | /www/wiki.youvivu.com/public_html/vendor/composer/autoload_static.php |
11 | /www/wiki.youvivu.com/public_html/vendor/swiftmailer/swiftmailer/lib/swift_required.php |
12 | /www/wiki.youvivu.com/public_html/vendor/swiftmailer/swiftmailer/lib/classes/Swift.php |
13 | /www/wiki.youvivu.com/public_html/vendor/facebook/graph-sdk/src/Facebook/polyfills.php |
14 | /www/wiki.youvivu.com/public_html/vendor/facebook/php-sdk-v4/src/Facebook/polyfills.php |
15 | /www/wiki.youvivu.com/public_html/vendor/crada/phalcon-user-plugin/lib/swift_required.php |
16 | /www/wiki.youvivu.com/public_html/app/modules/Application/Mvc/View/Engine/Volt.php |
17 | /www/wiki.youvivu.com/public_html/app/modules/Application/Widget/Proxy.php |
18 | /www/wiki.youvivu.com/public_html/app/modules/Application/Cache/Manager.php |
19 | /www/wiki.youvivu.com/public_html/app/modules/Cms/Model/Configuration.php |
20 | /www/wiki.youvivu.com/public_html/app/modules/Application/Acl/DefaultAcl.php |
21 | /www/wiki.youvivu.com/public_html/app/config/acl.php |
22 | /www/wiki.youvivu.com/public_html/app/modules/Application/Assets/Manager.php |
23 | /www/wiki.youvivu.com/public_html/app/modules/Application/Assets/Filter/Less.php |
24 | /www/wiki.youvivu.com/public_html/app/modules/Application/Mvc/Helper.php |
25 | /www/wiki.youvivu.com/public_html/app/modules/Menu/Helper/Menu.php |
26 | /www/wiki.youvivu.com/public_html/app/modules/Application/Mvc/Router/DefaultRouter.php |
27 | /www/wiki.youvivu.com/public_html/app/modules/Index/Routes.php |
28 | /www/wiki.youvivu.com/public_html/app/modules/Application/Mvc/Helper/CmsCache.php |
29 | /www/wiki.youvivu.com/public_html/app/modules/Admin/Routes.php |
30 | /www/wiki.youvivu.com/public_html/app/modules/Page/Routes.php |
31 | /www/wiki.youvivu.com/public_html/app/modules/Publication/Routes.php |
32 | /www/wiki.youvivu.com/public_html/app/modules/Publication/Model/Type.php |
33 | /www/wiki.youvivu.com/public_html/app/modules/Application/Mvc/Model/Model.php |
34 | /www/wiki.youvivu.com/public_html/app/modules/Seo/Routes.php |
35 | /www/wiki.youvivu.com/public_html/app/modules/Tree/Init.php |
36 | /www/wiki.youvivu.com/public_html/app/modules/Tree/Mvc/Helper.php |
37 | /www/wiki.youvivu.com/public_html/app/modules/Sitemap/Routes.php |
38 | /www/wiki.youvivu.com/public_html/app/modules/Api/Routes.php |
39 | /www/wiki.youvivu.com/public_html/app/modules/Account/Routes.php |
40 | /www/wiki.youvivu.com/public_html/app/modules/Media/Routes.php |
41 | /www/wiki.youvivu.com/public_html/app/modules/Application/Utils/ModuleName.php |
42 | /www/wiki.youvivu.com/public_html/app/modules/Publication/Module.php |
43 | /www/wiki.youvivu.com/public_html/app/plugins/CheckPoint.php |
44 | /www/wiki.youvivu.com/public_html/app/plugins/Localization.php |
45 | /www/wiki.youvivu.com/public_html/app/modules/Cms/Model/Translate.php |
46 | /www/wiki.youvivu.com/public_html/app/plugins/AdminLocalization.php |
47 | /www/wiki.youvivu.com/public_html/data/translations/admin/en.php |
48 | /www/wiki.youvivu.com/public_html/app/plugins/Acl.php |
49 | /www/wiki.youvivu.com/public_html/app/plugins/MobileDetect.php |
50 | /www/wiki.youvivu.com/public_html/app/modules/Publication/Controller/IndexController.php |
51 | /www/wiki.youvivu.com/public_html/app/modules/Application/Mvc/Controller.php |
52 | /www/wiki.youvivu.com/public_html/app/modules/Publication/Model/Helper/PublicationHelper.php |
53 | /www/wiki.youvivu.com/public_html/app/modules/Publication/Model/Publication.php |
54 | /www/wiki.youvivu.com/public_html/app/modules/Application/Cache/Keys.php |
55 | /www/wiki.youvivu.com/public_html/app/modules/Publication/Model/Translate/PublicationTranslate.php |
56 | /www/wiki.youvivu.com/public_html/app/modules/Application/Mvc/Model/Translate.php |
57 | /www/wiki.youvivu.com/public_html/app/modules/Publication/Model/Translate/TypeTranslate.php |
58 | /www/wiki.youvivu.com/public_html/app/modules/Application/Mvc/Helper/Title.php |
59 | /www/wiki.youvivu.com/public_html/app/modules/Application/Mvc/Helper/Meta.php |
60 | /www/wiki.youvivu.com/public_html/app/modules/Page/Model/Helper/PageHelper.php |
61 | /www/wiki.youvivu.com/public_html/app/modules/Page/Model/Page.php |
62 | /www/wiki.youvivu.com/public_html/vendor/crada/phalcon-user-plugin/lib/Auth/Auth.php |
63 | /www/wiki.youvivu.com/public_html/app/modules/Seo/Plugin/SeoManager.php |
64 | /www/wiki.youvivu.com/public_html/app/modules/Seo/Model/Manager.php |
65 | /www/wiki.youvivu.com/public_html/app/plugins/Title.php |
66 | /www/wiki.youvivu.com/public_html/data/cache/volt/%%www%%wiki.youvivu.com%%public_html%%app%%modules%%publication%%views%%index%%publication.volt.php |
67 | /www/wiki.youvivu.com/public_html/app/modules/Image/Storage.php |
Memory | |
---|---|
Usage | 3932160 |