/** * Build <input type="checkbox" checked {$properties} /> response * {@inheritDoc} * @see \Ffcms\Core\Helper\HTML\Form\iField::make() * @throws \Ffcms\Core\Exception\NativeException * @throws \Ffcms\Core\Exception\SyntaxException */ public function make() { // check if options is defined $options = $this->properties['options']; if (!Obj::isIterable($options)) { throw new SyntaxException('Options for field ' . self::nohtml($this->name) . ' is not iterable'); } unset($this->properties['options']); // set field type $this->properties['type'] = 'checkbox'; // set this field as array html dom object $this->properties['name'] .= '[]'; unset($this->properties['value'], $this->properties['id']); $build = null; foreach ($options as $opt) { // check if this is active element if (Obj::isArray($this->value) && Arr::in($opt, $this->value)) { $this->properties['checked'] = null; } else { unset($this->properties['checked']); // remove checked if it setted before } $this->properties['value'] = $opt; // apply structured checkboxes style for each item $build .= App::$View->render('native/form/multi_checkboxes_list', ['item' => self::buildSingleTag('input', $this->properties) . self::nohtml($opt)]); } return $build; }
/** * Construct listing elements,property's and future's * @param array $elements * @return string */ public static function display($elements) { // check input elements if (!Arr::in($elements['type'], ['ul', 'ol']) || count($elements['items']) < 1) { return null; } // initialize new DOM model $dom = new Dom(); // return DOM-HTML, build based on closures! return $dom->{$elements['type']}(function () use($dom, $elements) { // prepare output avg variable $itemHTML = null; // get active order level $orderActiveLink = false; if (isset($elements['activeOrder'])) { $orderActiveLink = $elements['activeOrder']; unset($elements['activeOrder']); } foreach ($elements['items'] as $item) { // sounds like dropdown array if (isset($item['dropdown']) && isset($item['items'])) { $itemHTML .= self::buildDropdown($dom, $item); } elseif (isset($item['link'])) { // looks like link item $itemHTML .= self::buildLink($dom, $item, $orderActiveLink); } else { // just text item $itemHTML .= self::buildText($dom, $item); } } return $itemHTML; }, $elements['property']); }
/** * Upload files from ckeditor * @param string $type * @return string * @throws NativeException * @throws \Ffcms\Core\Exception\SyntaxException */ public function actionUpload($type) { /** @var $loadFile \Symfony\Component\HttpFoundation\File\UploadedFile */ $loadFile = App::$Request->files->get('upload'); if ($loadFile === null || $loadFile->getError() !== 0) { return $this->errorResponse(__('File upload failed')); } // get file extension $fileExt = '.' . $loadFile->guessExtension(); // check if this request type is allowed if ($this->allowedExt[$type] === null || !Obj::isArray($this->allowedExt[$type])) { throw new NativeException('Hack attempt'); } // check if this file extension is allowed to upload if (!Arr::in($fileExt, $this->allowedExt[$type])) { return $this->errorResponse(__('This file type is not allowed to upload')); } $date = Date::convertToDatetime(time(), 'd-m-Y'); // create file hash based on name-size $fileNewName = App::$Security->simpleHash($loadFile->getFilename() . $loadFile->getSize()) . $fileExt; $savePath = Normalize::diskFullPath('/upload/' . $type . '/' . $date); // save file from tmp to regular $loadFile->move($savePath, $fileNewName); // generate URI of uploaded file $url = '/upload/' . $type . '/' . $date . '/' . $fileNewName; return App::$View->render('editor/load_success', ['callbackId' => (int) App::$Request->query->get('CKEditorFuncNum'), 'url' => $url], __DIR__); }
/** * Delete user row from database * @param int $id * @return string * @throws \Ffcms\Core\Exception\SyntaxException * @throws \Ffcms\Core\Exception\NativeException * @throws NotFoundException */ public function actionDelete($id = null) { // check if id is passed or get data from GET as array ids if ($id === 0 || (int) $id < 1) { $ids = $this->request->query->get('selected'); if (Obj::isArray($ids) && Arr::onlyNumericValues($ids)) { $id = $ids; } else { throw new NotFoundException('Bad conditions'); } } else { $id = [$id]; } // initialize delete model $model = new FormUserDelete($id); // check if users is found if ($model->users === null) { throw new NotFoundException(__('Users are not found')); } // check if delete is submited if ($model->send() && $model->validate()) { $model->delete(); App::$Session->getFlashBag()->add('success', __('Users and them data are successful removed')); $this->response->redirect('user/index'); } // set view response return $this->view->render('user_delete', ['model' => $model]); }
/** * FormInstall constructor. Pass applications object from controller * @param $apps * @param string $type * @throws SyntaxException */ public function __construct(array $apps = null, $type) { $this->_apps = $apps; // check if passed type is allowed to use if (!Arr::in($type, ['app', 'widget'])) { throw new SyntaxException('The type of extension is not defined!'); } $this->_type = $type; parent::__construct(); }
/** * Get user avatar full url for current object * @param string $type * @return string */ public function getAvatarUrl($type = 'small') { $default = '/upload/user/avatar/' . $type . '/default.jpg'; if (!Arr::in($type, ['small', 'big', 'medium'])) { return MainApp::$Alias->scriptUrl . $default; } $route = '/upload/user/avatar/' . $type . '/' . $this->user_id . '.jpg'; if (File::exist($route)) { return MainApp::$Alias->scriptUrl . $route . '?mtime=' . File::mTime($route); } return MainApp::$Alias->scriptUrl . $default; }
/** * Build output content by tag name, tag content and properties * @param string $name * @param string|null $content * @param array|null $properties * @return null|string */ private function buildTag($name, $content = null, array $properties = null) { // looks like a single tag, <img src="" class="" />, <hr class="" /> if (Arr::in($name, self::$singleTags)) { return '<' . $name . self::applyProperties($properties) . ' />'; } elseif (Arr::in($name, self::$containerTags)) { // looks like a container tag, <div class=""></div> return '<' . $name . self::applyProperties($properties) . '>' . $content . '</' . $name . '>'; } // empty response return null; }
/** * Pass init params */ public function init() { if ($this->language === null) { $this->language = App::$Request->getLanguage(); } if ($this->targetClass === null) { $this->targetClass = 'wysiwyg'; } if ($this->config === null || !Arr::in($this->config, ['config-small', 'config-full', 'config-medium'])) { $this->config = 'config-default'; } $this->baseUrl = App::$Alias->scriptUrl . '/vendor/phpffcms/ffcms-ckeditor/assets'; }
/** * Get single row by defined type and sys_name with query caching * @param string $type * @param string|array $sys_name * @return mixed|null * @throws SyntaxException */ public static function getItem($type, $sys_name) { foreach (self::all() as $object) { if ($object->type === $type) { //&& $object->sys_name === $sys_name) { if (Obj::isArray($sys_name) && Arr::in($object->sys_name, $sys_name)) { // many different app name - maybe alias or something else return $object; } elseif (Obj::isString($sys_name) && $object->sys_name === $sys_name) { return $object; } } } return null; }
/** * Check passed params from constructor * @throws \Ffcms\Core\Exception\SyntaxException */ public function before() { // check rule type if (!Arr::in($this->type, ['Alias', 'Callback'])) { throw new SyntaxException(); } // check loader env type if (!Arr::in($this->loader, ['Front', 'Admin', 'Api'])) { throw new SyntaxException(); } // prepare source path if ($this->type === 'Alias') { $this->source = '/' . trim($this->source, '/'); } else { $this->source = ucfirst($this->source); } if (!isset($this->_cfg[$this->type][$this->loader][$this->source])) { throw new SyntaxException(); } }
/** * List category content * @throws NotFoundException * @throws \Ffcms\Core\Exception\SyntaxException * @throws \Ffcms\Core\Exception\NativeException * @return string */ public function actionList() { $path = $this->request->getPathWithoutControllerAction(); $configs = $this->getConfigs(); $page = (int) $this->request->query->get('page', 0); $sort = (string) $this->request->query->get('sort', 'newest'); $itemCount = (int) $configs['itemPerCategory']; // build special model with content list and category list information $model = new EntityCategoryList($path, $configs, $page, $sort); // prepare query string (?a=b) for pagination if sort is defined $sortQuery = null; if (Arr::in($sort, ['rating', 'views'])) { $sortQuery = ['sort' => $sort]; } // build pagination $pagination = new SimplePagination(['url' => ['content/list', $path, null, $sortQuery], 'page' => $page, 'step' => $itemCount, 'total' => $model->getContentCount()]); // define list event App::$Event->run(static::EVENT_CONTENT_LIST, ['model' => $model]); // draw response view return $this->view->render('list', ['model' => $model, 'pagination' => $pagination, 'configs' => $configs]); }
/** * Add user in database * @return string * @throws NativeException */ public function actionAdduser() { echo "Login:"******"Email:"; $email = Console::$Input->read(); if (!Str::isEmail($email)) { throw new NativeException('Email is bad'); } echo "Password:"******"RoleId (1 = onlyread, 2 = user, 3 = moderator, 4 = admin):"; $role = (int) Console::$Input->read(); if (!Arr::in($role, [1, 2, 3, 4])) { $role = 2; } if (User::isMailExist($email) || User::isLoginExist($login)) { throw new NativeException('User with this email or login is always exist'); } $salt = Console::$Properties->get('passwordSalt'); $user = new User(); $user->login = $login; $user->email = $email; $user->password = Security::password_hash($pass, $salt); $user->role_id = $role; $user->save(); $profile = new Profile(); $profile->user_id = $user->id; $profile->save(); return 'User was successful added to database!'; }
/** * Build <select @properties>@optionsDOM</select> container * {@inheritDoc} * @see \Ffcms\Core\Helper\HTML\Form\iField::make() */ public function make() { // check if options is defined $options = $this->properties['options']; $optionsKey = (bool) $this->properties['optionsKey']; if (!Obj::isIterable($options)) { throw new SyntaxException('Options for field ' . self::nohtml($this->name) . ' is not iterable'); } unset($this->properties['options']); // set global field type $this->properties['type'] = 'select'; // add multiple element $this->properties['multiple'] = null; $this->properties['name'] .= '[]'; unset($this->properties['value'], $this->properties['options'], $this->properties['optionsKey']); // build options as HTML DOM element: <option @value>@text</option> $optionsDOM = null; foreach ($options as $val => $text) { // check if options key is value $optionProperty = null; if ($optionsKey === true) { $optionProperty['value'] = $val; // check if current element is active if (Obj::isArray($this->value) && Arr::in((string) $val, $this->value)) { $optionProperty['selected'] = 'selected'; } } else { if (Obj::isArray($this->value) && Arr::in((string) $text, $this->value)) { $optionProperty['selected'] = 'selected'; } } $optionsDOM .= self::buildContainerTag('option', $optionProperty, $text); } // build <select @properties>@optionsDOM</select> return self::buildContainerTag('select', $this->properties, $optionsDOM, true); }
$widgetControllers[] = 'Widget'; ?> <li<?php echo Arr::in(\App::$Request->getController(), $appControllers) ? ' class="active"' : null; ?> > <a href="#"><i class="fa fa-plug fa-fw"></i> <?php echo __('Applications'); ?> <span class="fa arrow"></span></a> <?php echo Listing::display(['type' => 'ul', 'property' => ['class' => 'nav nav-second-level'], 'activeOrder' => 'controller', 'items' => $appMenuItems]); ?> </li> <li<?php echo Arr::in(\App::$Request->getController(), $widgetControllers) ? ' class="active"' : null; ?> > <a href="#"><i class="fa fa-puzzle-piece fa-fw"></i> <?php echo __('Widgets'); ?> <span class="fa arrow"></span></a> <?php echo Listing::display(['type' => 'ul', 'property' => ['class' => 'nav nav-second-level'], 'activeOrder' => 'controller', 'items' => $widgetMenuItems]); ?> </li> </ul> </div> <!-- /.sidebar-collapse --> </div> <!-- /.navbar-static-side -->
} foreach ($model->items as $item) { ?> <article class="article-item" itemscope="itemscope" itemtype="https://schema.org/NewsArticle"> <h2 itemprop="name"> <a href="<?php echo \App::$Alias->baseUrl . $item['uri']; ?> "> <?php echo $item['title']; ?> </a> </h2> <?php if (Arr::in(true, $catMeta)) { ?> <div class="meta"> <?php if ($catConfigs['showCategory'] === true) { ?> <span class="spaced"><i class="fa fa-list"></i> <?php echo Url::link(['content/list', $item['category']->path], \App::$Translate->getLocaleText($item['category']->title), ['itemprop' => 'genre']); ?> </span> <?php } ?> <?php if ($catConfigs['showDate'] === true) {
/** * Build pathway from array $to. Example: ['controller/action', 'id', 'add', ['get' => 'value'], '#anchor'] * @param array $to * @param bool $encode * @return string|null */ public static function buildPathway(array $to = null, $encode = true) { // if empty passed - let show main page if ($to === null) { return null; } $response = Str::lowerCase(trim($to[0], '/')); // controller/action list($controller, $action) = explode('/', $response); $routing = App::$Properties->getAll('Routing'); // sounds like dynamic callback if (Str::startsWith('@', $controller)) { $controller = trim($controller, '@'); // search callback in properties if (isset($routing['Callback'][env_name]) && Arr::in($controller, $routing['Callback'][env_name])) { $pathInject = array_search($controller, $routing['Callback'][env_name]); // if path is founded - lets set source if ($pathInject !== false) { $controller = Str::lowerCase($pathInject); } } // if controller still looks like path injection - define last entity like controller name if (Str::contains('\\', $controller)) { $controller = Str::lastIn($controller, '\\', true); } $response = $controller . '/' . $action; } // check if controller and action is defined if (Str::likeEmpty($controller) || Str::likeEmpty($action)) { return null; } // id is defined? if (isset($to[1]) && !Str::likeEmpty($to[1])) { $response .= '/' . self::safeUri($to[1], $encode); } // add param is defined? if (isset($to[2]) && !Str::likeEmpty($to[2])) { $response .= '/' . self::safeUri($to[2], $encode); } // try to find static alias if (isset($routing['Alias'][env_name]) && Arr::in('/' . $response, $routing['Alias'][env_name])) { $pathAlias = array_search('/' . $response, $routing['Alias'][env_name]); if ($pathAlias !== false) { $response = Str::lowerCase(trim($pathAlias, '/')); } } // parse get attributes if (isset($to[3]) && Obj::isArray($to[3]) && count($to[3]) > 0) { // check if anchor bindig is exist $anchor = false; if (isset($to[3]['#']) && Obj::isString($to[3]['#']) && Str::startsWith('#', $to[3]['#'])) { $anchor = $to[3]['#']; unset($to[3]['#']); } $queryString = http_build_query($to[3]); if (Str::length($queryString) > 0) { $response .= '?' . http_build_query($to[3]); } if ($anchor !== false) { $response .= $anchor; } } // parse anchor link part #item-related-id-1 if (isset($to[4]) && Obj::isString($to[4]) && Str::startsWith('#', $to[4])) { $response .= $to[4]; } return $response; }
/** * Set GET param to property array * @param int|string $page_id * @return array */ protected function setUrlPage($page_id) { $url = $this->url; switch (count($url)) { // check nulls if not set case 1: // only controller/action is defined $url[1] = null; $url[2] = null; break; case 2: $url[2] = null; break; } // add page param if > 0 if ((int) $page_id > 0) { // merge with ?page if query is not empty if (Obj::isArray($url[3])) { $url[3] = Arr::merge($url[3], ['page' => $page_id]); } else { // just set ?page=$page_id $url[3] = ['page' => $page_id]; } } return $url; }
/** * Append translation data from exist full path * @param string $path * @return bool */ public function append($path) { $path = Normalize::diskFullPath($path); // check if file exist if (!File::exist($path)) { return false; } // load file translations $addTranslation = (require $path); if (!Obj::isArray($addTranslation)) { return false; } // merge data $this->cached = Arr::merge($this->cached, $addTranslation); return true; }
/** * Check if field is file or null * @param object $object * @param $value * @return bool */ public static function isFile($object, $value) { // allow empty fields, "required" option filter that if ($object === null) { return true; } $all = false; // if string is given if (!Obj::isArray($value)) { if ($value === '*') { $all = true; } else { $value = [$value]; } } // input file is not object? if ($object === null || !Obj::isObject($object)) { return false; } // get guess file type, based on mime-type $type = $object->guessExtension(); if ($type === null) { return false; } return $all ? true : Arr::in($type, $value); }
$breadcrumbs[] = __('Content') . ': ' . Str::sub($this->title, 0, 40); } $this->breadcrumbs = $breadcrumbs; } $properties = ['date' => (bool) $model->getCategory()->getProperty('showDate'), 'author' => (bool) $model->getCategory()->getProperty('showAuthor'), 'views' => (bool) $model->getCategory()->getProperty('showViews'), 'category' => (bool) $model->getCategory()->getProperty('showCategory'), 'rating' => (bool) $model->getCategory()->getProperty('showRating'), 'tags' => (bool) $model->getCategory()->getProperty('showTags')]; $showComments = (bool) $model->getCategory()->getProperty('showComments'); $showPoster = (bool) $model->getCategory()->getProperty('showPoster'); ?> <article class="article-item" itemscope="itemscope" itemtype="https://schema.org/NewsArticle"> <h1><?php echo $model->title; ?> </h1> <?php if (Arr::in(true, $properties)) { ?> <div class="meta"> <?php if ($properties['category'] === true) { ?> <span class="spaced"><i class="fa fa-list"></i> <?php echo Url::link(['content/list', $model->catPath, null, [], false], $model->catName, ['itemprop' => 'genre']); ?> </span> <?php } ?> <?php if ($properties['date'] === true) { ?>
/** * Prepare static pathway aliasing for routing * @param array|null $map * @param string|null $pathway * @return string */ private function findStaticAliases(array $map = null, $pathway = null) { if ($map === null) { return $pathway; } // current pathway is found as "old path" (or alias target). Make redirect to new pathway. if (Arr::in($pathway, $map)) { // find "new path" as binding uri slug $binding = array_search($pathway, $map, true); // build url to redirection $url = $this->getSchemeAndHttpHost() . $this->getBasePath() . '/'; if (App::$Properties->get('multiLanguage')) { $url .= $this->language . '/'; } $url .= ltrim($binding, '/'); $redirect = new Redirect($url); $redirect->send(); exit; } // current pathway request is equal to path alias. Set alias to property. if (array_key_exists($pathway, $map)) { $pathway = $map[$pathway]; $this->aliasPathTarget = $pathway; } return $pathway; }
/** * Check if user role contains permission * @param string $permission * @return bool */ public function can($permission) { // Role::get(id) is not initialized if ($this->permissions === null) { return false; } // global admin $permArray = explode(';', $this->permissions); if (count($permArray) < 1) { return false; } // admin can all :) if (Arr::in('global/all', $permArray)) { return true; } // check if current permission in user permission role if (Arr::in($permission, $permArray)) { return true; } return false; }
/** * Try to download and parse remote avatar * @param string $url * @param int $userId */ protected function parseAvatar($url, $userId) { // check if user is defined if ((int) $userId < 1) { return; } // check remote image extension $imageExtension = Str::lastIn($url, '.', true); if (!Arr::in($imageExtension, ['png', 'gif', 'jpg', 'jpeg'])) { return; } // try to get image binary data $imageContent = Url::download($url); if ($imageContent === null || Str::likeEmpty($imageContent)) { return; } // write image to filesystem $imagePath = '/upload/user/avatar/original/' . $userId . '.' . $imageExtension; $write = File::write($imagePath, $imageContent); if ($write === false) { return; } // try to write and resize file try { $fileObject = new FileObject(root . $imagePath); $avatarUpload = new FormAvatarUpload(); $avatarUpload->resizeAndSave($fileObject, $userId, 'small'); $avatarUpload->resizeAndSave($fileObject, $userId, 'medium'); $avatarUpload->resizeAndSave($fileObject, $userId, 'big'); } catch (\Exception $e) { if (App::$Debug) { App::$Debug->addException($e); } } }
/** * Build content data to model properties * @param $records * @throws ForbiddenException * @throws NotFoundException */ private function buildContent($records) { $nullItems = 0; foreach ($records as $row) { /** @var Content $row */ // check title length on current language locale $localeTitle = $row->getLocaled('title'); if (Str::likeEmpty($localeTitle)) { ++$nullItems; continue; } // get snippet from full text for current locale $text = Text::snippet($row->getLocaled('text')); $itemPath = $this->categories[$row->category_id]->path; if (!Str::likeEmpty($itemPath)) { $itemPath .= '/'; } $itemPath .= $row->path; // prepare tags data $tags = $row->getLocaled('meta_keywords'); if (!Str::likeEmpty($tags)) { $tags = explode(',', $tags); } else { $tags = null; } $owner = App::$User->identity($row->author_id); // make a fake if user is not exist over id if ($owner === null) { $owner = new User(); } // check if current user can rate item $ignoredRate = App::$Session->get('content.rate.ignore'); $canRate = true; if (Obj::isArray($ignoredRate) && Arr::in((string) $row->id, $ignoredRate)) { $canRate = false; } if (!App::$User->isAuth()) { $canRate = false; } elseif ($owner->getId() === App::$User->identity()->getId()) { // own item $canRate = false; } // build result array $this->items[] = ['id' => $row->id, 'title' => $localeTitle, 'text' => $text, 'date' => Date::humanize($row->created_at), 'updated' => $row->updated_at, 'author' => $owner, 'poster' => $row->getPosterUri(), 'thumb' => $row->getPosterThumbUri(), 'thumbSize' => File::size($row->getPosterThumbUri()), 'views' => (int) $row->views, 'rating' => (int) $row->rating, 'canRate' => $canRate, 'category' => $this->categories[$row->category_id], 'uri' => '/content/read/' . $itemPath, 'tags' => $tags]; } if ($nullItems === $this->_contentCount) { throw new NotFoundException(__('Content is not founded')); } }
/** * Save model properties as configurations * @return bool */ public function makeSave() { $toSave = App::$Security->strip_php_tags($this->getAllProperties()); $stringSave = '<?php return ' . Arr::exportVar($toSave, null, true) . ';'; $cfgPath = '/Private/Config/Default.php'; if (File::exist($cfgPath) && File::writable($cfgPath)) { File::write($cfgPath, $stringSave); return true; } return false; }
/** * @param string $type * @param string $code * @return bool */ public function addPlainCode($type, $code) { $allowed = ['css', 'js']; if (!Arr::in($type, $allowed)) { return false; } $this->plainCode[$type][] = $code; return true; }
/** * Write configurations data from array to cfg file * @param string $configFile * @param array $data * @return bool */ public function writeConfig($configFile, array $data) { $path = '/Private/Config/' . ucfirst(Str::lowerCase($configFile)) . '.php'; if (!File::exist($path) || !File::writable($path)) { return false; } $saveData = '<?php return ' . Arr::exportVar($data) . ';'; File::write($path, $saveData); return true; }
/** * Check all params * @return bool */ public function checkAll() { return $this->checkPhpVersion() && $this->pdo && $this->gd && !Arr::in(false, $this->chmodCheck); }
/** * Prepare model attributes from passed objects * @throws ForbiddenException */ public function before() { $this->id = $this->_content->id; $this->title = $this->_content->getLocaled('title'); $this->text = $this->_content->getLocaled('text'); // check if title and text are exists if (Str::length($this->title) < 1 || Str::length($this->text) < 1) { throw new ForbiddenException(); } // get meta data $this->metaTitle = $this->_content->getLocaled('meta_title'); if (Str::likeEmpty($this->metaTitle)) { $this->metaTitle = $this->title; } $this->metaDescription = $this->_content->getLocaled('meta_description'); $tmpKeywords = $this->_content->getLocaled('meta_keywords'); $this->metaKeywords = explode(',', $tmpKeywords); // set content date, category data $this->createDate = Date::humanize($this->_content->created_at); $this->catName = $this->_category->getLocaled('title'); $this->catPath = $this->_category->path; // set user data if (App::$User->isExist($this->_content->author_id)) { $this->authorId = $this->_content->author_id; $profile = App::$User->identity($this->authorId)->getProfile(); $this->authorName = $profile->getNickname(); } $this->source = $this->_content->source; $this->views = $this->_content->views + 1; // check for dependence, add '' for general cat, ex: general/depend1/depend2/.../depend-n $catNestingArray = Arr::merge([0 => ''], explode('/', $this->catPath)); if ($catNestingArray > 1) { // latest element its a current nesting level, lets cleanup it array_pop($catNestingArray); $catNestingPath = null; foreach ($catNestingArray as $cPath) { $catNestingPath .= $cPath; // try to find category by path in db $record = ContentCategory::getByPath($catNestingPath); if ($record !== null && $record->count() > 0) { // if founded - add to nesting data $this->catNesting[] = ['name' => $record->getLocaled('title'), 'path' => $record->path]; } if (!Str::likeEmpty($catNestingPath)) { $catNestingPath .= '/'; } } } // build array of category nesting level $this->catNesting[] = ['name' => $this->catName, 'path' => $this->catPath]; // get gallery images and poster data $galleryPath = '/upload/gallery/' . $this->_content->id; // check if gallery folder is exist if (Directory::exist($galleryPath)) { $originImages = File::listFiles($galleryPath . '/orig/', ['.jpg', '.png', '.gif', '.jpeg', '.bmp', '.webp'], true); // generate poster data if (Arr::in($this->_content->poster, $originImages)) { // original poster $posterName = $this->_content->poster; $this->posterFull = $galleryPath . '/orig/' . $posterName; if (!File::exist($this->posterFull)) { $this->posterFull = null; } // thumb poster $posterSplit = explode('.', $posterName); array_pop($posterSplit); $posterCleanName = implode('.', $posterSplit); $this->posterThumb = $galleryPath . '/thumb/' . $posterCleanName . '.jpg'; if (!File::exist($this->posterThumb)) { $this->posterThumb = null; } } // generate full gallery foreach ($originImages as $image) { $imageSplit = explode('.', $image); array_pop($imageSplit); $imageClearName = implode('.', $imageSplit); // skip image used in poster if (Str::startsWith($imageClearName, $this->_content->poster)) { continue; } $thumbPath = $galleryPath . '/thumb/' . $imageClearName . '.jpg'; if (File::exist($thumbPath)) { $this->galleryItems[$thumbPath] = $galleryPath . '/orig/' . $image; } } } // set rating data $this->rating = $this->_content->rating; $ignoredRate = App::$Session->get('content.rate.ignore'); $this->canRate = true; if (Obj::isArray($ignoredRate) && Arr::in((string) $this->id, $ignoredRate)) { $this->canRate = false; } if (!App::$User->isAuth()) { $this->canRate = false; } elseif ($this->authorId === App::$User->identity()->getId()) { $this->canRate = false; } // update views count $this->_content->views += 1; $this->_content->save(); }
/** * Display nav listing block * @param array $elements */ public static function display($elements) { // check if elements isn't empty and contains rows if (!Obj::isArray($elements) || count($elements['items']) < 1) { return null; } // prepare tab order if ($elements['tabAnchor'] === null) { $elements['tabAnchor'] = Str::randomLatin(mt_rand(6, 12)); } // set global element properties $blockProperty = []; if ($elements['blockProperty'] !== null) { if (Obj::isArray($elements['blockProperty'])) { $blockProperty = $elements['blockProperty']; } unset($elements['blockProperty']); } // check if items have defined active order $activeDefined = Arr::in(true, Arr::ploke('active', $elements['items'])); // prepare tab content $tabContent = null; $tabIdx = 1; // initialize dom model $dom = new Dom(); // prepare items to drow listing $items = []; foreach ($elements['items'] as $item) { // its just a link, drow it as is if ($item['type'] === 'link') { $items[] = $item; } elseif ($item['type'] === 'dropdown') { // build bootstrap dropdown properties $item['dropdown'] = ['class' => 'dropdown-toggle', 'data-toggle' => 'dropdown', 'href' => '#']; $item['property']['class'] = Str::concat(' ', 'dropdown', $item['property']['class']); $items[] = $item; } elseif ($item['type'] === 'tab') { $activeObject = false; $item['type'] = 'link'; // fix for global Listing builder $item['link'] = '#' . $elements['tabAnchor'] . $tabIdx; $item['property']['role'] = 'presentation'; // check if active definition is exist in elements options if ($activeDefined) { if ($item['active'] === true) { $activeObject = true; } } elseif ($tabIdx === 1) { // if not exist set first as active $activeObject = true; } // mark active tab if ($activeObject === true) { $item['property']['class'] .= (Str::length($item['property']['class']) > 0 ? ' ' : null) . 'active'; } // tab special properties for bootstrap $item['linkProperty']['aria-controls'] = $elements['tabAnchor'] . $tabIdx; $item['linkProperty']['role'] = 'tab'; $item['linkProperty']['data-toggle'] = 'tab'; $itemContent = $item['content']; unset($item['content']); $items[] = $item; // draw tab content $tabContent .= $dom->div(function () use($item, $itemContent) { if ($item['html'] === true) { if ($item['!secure'] === true) { return $itemContent; } else { return self::safe($itemContent, true); } } else { return self::nohtml($itemContent); } }, ['role' => 'tabpanel', 'class' => 'tab-pane fade' . ($activeObject === true ? ' in active' : null), 'id' => $elements['tabAnchor'] . $tabIdx]); $tabIdx++; } } // check if global class "nav" isset if ($elements['property']['class'] !== null) { if (!Str::contains('nav ', $elements['property']['class'])) { $elements['property']['class'] = 'nav ' . $elements['property']['class']; } } else { $elements['property']['class'] = 'nav'; } // render final output return $dom->div(function () use($elements, $items, $tabContent, $dom) { // drow listing $listing = Listing::display(['type' => 'ul', 'property' => $elements['property'], 'activeOrder' => $elements['activeOrder'], 'items' => $items]); // drow tabs if isset if ($tabContent !== null) { $tabContent = $dom->div(function () use($tabContent) { return $tabContent; }, ['class' => 'tab-content']); } return $listing . $tabContent; }, $blockProperty); }