public function before() { if (!\CMF\Auth::check(null, 'view', 'admin_site')) { \Response::redirect("/admin/login?next=" . \Uri::string(), 'location'); } \Lang::$autosave = false; // Find the lang from the session, or from the user if ($this->lang_enabled = \Config::get('cmf.languages.enabled', false)) { $lang = \Session::get('cmf.admin.language'); if ($lang === null) { $user = \CMF\Auth::current_user(); $lang = $user->default_language; } if (!empty($lang) && strlen($lang) !== 0 && $lang !== null) { \CMF::setLang($lang); } } // Allows us to set the interface template via an integer $this->mode = \Input::param('_mode', 'default'); $this->interface_template = \Config::get('cmf.admin.interface_templates.' . $this->mode); // A unique ID that can be passed through $this->cid = \Input::param('_cid', 'none'); // Lang info $this->current_lang = \Lang::get_lang(); $this->fallback_lang = \Lang::$fallback; $this->lang_lines = \Lang::$lines; }
private function uploadImage() { // files storage folder $public_dir = $_SERVER['DOCUMENT_ROOT'] . DS . 'uploads/images/'; if (!($exists = is_dir($public_dir))) { $exists = @mkdir($public_dir, 0775, true); } $_FILES['file']['type'] = strtolower($_FILES['file']['type']); if ($_FILES['file']['type'] == 'image/png' || $_FILES['file']['type'] == 'image/jpg' || $_FILES['file']['type'] == 'image/gif' || $_FILES['file']['type'] == 'image/jpeg' || $_FILES['file']['type'] == 'image/pjpeg') { // setting file's mysterious name //$filename = md5(date('YmdHis')).'.'.$extension; $path_parts = pathinfo($_FILES['file']['name']); $raw_filename = preg_replace("/\\.[^.\\s]{3,4}\$/", "", $_FILES['file']['name']); $filename = \CMF::slug($raw_filename) . '.' . $path_parts['extension']; $file = $public_dir . $filename; if (file_exists($file)) { $file = $public_dir . date('ymdHis') . $filename; } // copying copy($_FILES['file']['tmp_name'], $file); // displaying file $array = array('filelink' => '/uploads/images/' . $filename); return stripslashes(json_encode($array)); } }
/** inheritdoc */ public static function settings($user_settings) { $settings = parent::settings($user_settings); // Populate the Bing API key if not already present $api_key = \Arr::get($settings, 'api_key', false); if (empty($api_key)) { $settings['api_key'] = \CMF::getSetting(\Arr::get($settings, 'api_key_setting', 'bing_maps_api_key')); } return $settings; }
/** * Renders the field's form element for editing in the admin site * @see \Admin::getFieldSettings() * @param mixed $value The current value of the property, if there is one * @param array $settings Field settings, created through \Admin::getFieldSettings() * @param object $model The model, if it is being edited. * @return string The form control */ public static function displayForm($value, &$settings, $model) { $class = get_called_class(); $settings = static::settings($settings); $include_label = isset($settings['label']) ? $settings['label'] : true; $required = isset($settings['required']) ? $settings['required'] : false; $errors = $model->getErrorsForField($settings['mapping']['fieldName']); $has_errors = count($errors) > 0; $input_attributes = isset($settings['input_attributes']) ? $settings['input_attributes'] : array('class' => 'input-xxlarge'); if (!isset($input_attributes['id'])) { $input_attributes['id'] = 'form_' . $settings['mapping']['fieldName']; } $attributes = array('class' => 'controls control-group' . ($has_errors ? ' error' : '') . ' field-type-' . $class::type($settings)); $label_text = $settings['title'] . ($required ? ' *' : ''); // Translation? if (\CMF::$lang_enabled && !\CMF::langIsDefault() && isset($settings['mapping']['columnName']) && $model->isTranslatable($settings['mapping']['columnName'])) { // If there is no translation if (!$model->hasTranslation($settings['mapping']['columnName'])) { $attributes['class'] .= ' no-translation'; $input_attributes['class'] .= ' no-translation'; $label_text = '<img class="lang-flag" src="' . \Uri::create('/admin/assets/img/lang/' . \CMF::defaultLang() . '.png') . '" /> ' . $label_text; } else { $label_text = '<img class="lang-flag" src="' . \Uri::create('/admin/assets/img/lang/' . \CMF::lang() . '.png') . '" /> ' . $label_text; } } // Description? $description = isset($settings['description']) ? '<span class="help-block">' . $settings['description'] . '</span>' : ''; // Build the input $input = '<input type="text" name="' . $settings['mapping']['fieldName'] . '" ' . array_to_attr($input_attributes) . ' value="' . \Security::htmlentities(strval($value), ENT_QUOTES) . '" />'; // Build the label $label = !$include_label ? '' : html_tag('label', array('class' => 'item-label', 'for' => $settings['mapping']['fieldName']), $label_text . ($has_errors ? ' - ' . $errors[0] : '')); // Prepend or append things... if (isset($settings['prepend'])) { $input = html_tag('div', array('class' => 'input-prepend'), html_tag('span', array('class' => 'add-on'), $settings['prepend']) . $input); } if (isset($settings['append'])) { $input = html_tag('div', array('class' => 'input-append'), $input . html_tag('span', array('class' => 'add-on'), $settings['append'])); } // Don't wrap the input if wrap is set to false if (isset($settings['wrap']) && $settings['wrap'] === false) { return $label . $input; } // Add the 'keep updated' control if the field has a template if (isset($settings['template']) && !empty($settings['template'])) { $attributes['class'] .= ' field-with-controls field-with-template'; $auto_update_setting = 'settings[' . $settings['mapping']['fieldName'] . '][auto_update]'; $auto_update_content = \Form::hidden($auto_update_setting, '0', array()) . html_tag('label', array('class' => 'checkbox auto-update-label'), \Form::checkbox($auto_update_setting, '1', \Arr::get($settings, 'auto_update', true), array('class' => 'auto-update')) . strtolower(\Lang::get('admin.common.auto_update'))); $auto_update = html_tag('div', array('class' => 'controls-top'), $auto_update_content); $label .= $auto_update; return array('content' => html_tag('div', $attributes, $label . $description . $input) . '<div class="clear"><!-- --></div>', 'widget' => false, 'assets' => array('js' => array('/admin/assets/js/twig.min.js', '/admin/assets/js/fields/template.js')), 'js_data' => $settings); } return html_tag('div', $attributes, $label . $description . $input); }
/** * An editor view for the fuel lang entries */ public function get_terms() { $this->template = 'admin/lang/terms.twig'; // Determine what's in the left and right cols $this->lang_lft = \Arr::get(\Lang::$fallback, '0', 'en'); $this->lang_rgt = \CMF::lang(); // Get the common group $result_lft = \Lang::load("common.db", 'common', $this->lang_lft, true, true); $result_rgt = \Lang::load("common.db", 'common', $this->lang_rgt, true, true); $this->result_lft = $result_lft; $this->result_rgt = $result_rgt; $this->lines = \Arr::get(\Lang::$lines, \Lang::$fallback[0], array()); }
/** inheritdoc */ public static function displayForm($value, &$settings, $model) { $settings = static::settings($settings); $include_label = isset($settings['label']) ? $settings['label'] : true; $required = isset($settings['required']) ? $settings['required'] : false; $errors = $model->getErrorsForField($settings['mapping']['fieldName']); $has_errors = count($errors) > 0; $attributes = array('class' => 'controls control-group ' . ($has_errors ? ' error' : '')); $input_attributes = isset($settings['input_attributes']) ? $settings['input_attributes'] : array('class' => 'input-xxlarge'); //add redactor to the class for the field $input_attributes['class'] = $input_attributes['class'] . " redactor"; $label_text = $settings['title'] . ($required ? ' *' : ''); $input = \Form::textarea($settings['mapping']['fieldName'], strval($value), $input_attributes); // Translation? if (\CMF::$lang_enabled && !\CMF::langIsDefault() && $model->isTranslatable($settings['mapping']['columnName'])) { // If there is no translation if (!$model->hasTranslation($settings['mapping']['columnName'])) { $attributes['class'] .= ' no-translation'; $label_text = '<span class="no-translation"><img class="lang-flag" src="' . \Uri::create('/admin/assets/img/lang/' . \CMF::defaultLang() . '.png') . '" /> ' . $label_text . '</span>'; } else { $label_text = '<img class="lang-flag" src="' . \Uri::create('/admin/assets/img/lang/' . \CMF::lang() . '.png') . '" /> ' . $label_text; } } // Build the label $label = !$include_label ? '' : \Form::label($label_text . ($has_errors ? ' - ' . $errors[0] : ''), $settings['mapping']['fieldName'], array('class' => 'item-label')); // Set up required information for any links specified if (isset($settings['links']) && is_array($settings['links'])) { $links = array(); foreach ($settings['links'] as $link_type => $link) { if (!class_exists($link_type)) { continue; } $link['table_name'] = \CMF\Admin::getTableForClass($link_type); $link['singular'] = $link_type::singular(); $link['plural'] = $link_type::plural(); $link['icon'] = $link_type::icon(); $links[$link_type] = $link; } $settings['links'] = $links; } // Return only the field and label if no wrap is required if (isset($settings['wrap']) && $settings['wrap'] === false) { return $label . $input; } // Return the widget if (isset($settings['widget']) && $settings['widget'] === true) { return array('assets' => array(), 'content' => $input, 'widget' => true, 'widget_title' => $label_text, 'widget_icon' => 'align-left', 'js_data' => $settings); } // Return the normal field return array('assets' => array(), 'content' => html_tag('div', $attributes, $label . $input), 'widget' => false, 'js_data' => $settings); }
/** @inheritdoc */ public static function displayForm($value, &$settings, $model) { $settings = static::settings($settings); $settings['label'] = isset($settings['label']) ? $settings['label'] : true; $settings['required'] = isset($settings['required']) ? $settings['required'] : false; $settings['errors'] = $model->getErrorsForField($settings['mapping']['fieldName']); $settings['has_errors'] = count($settings['errors']) > 0; $attributes = array('class' => 'field-type-file video controls control-group' . ($settings['has_errors'] ? ' error' : ''), 'data-field-name' => $settings['mapping']['fieldName'], 'id' => 'field_' . \CMF::slug($settings['mapping']['fieldName'])); $value = static::getValue($value, $settings, $model); $content = strval(\View::forge('admin/fields/video.twig', array('settings' => $settings, 'value' => $value), false)); $settings['value'] = $value; if (!(isset($settings['wrap']) && $settings['wrap'] === false)) { $content = html_tag('div', $attributes, $content); } return array('content' => $content, 'widget' => false, 'assets' => array(), 'js_data' => $settings); }
public static function show_production_error(\Exception $e) { // when we're on CLI, always show the php error if (\Fuel::$is_cli) { return static::show_php_error($e); } if (!headers_sent()) { $protocol = \Input::server('SERVER_PROTOCOL') ? \Input::server('SERVER_PROTOCOL') : 'HTTP/1.1'; header($protocol . ' 500 Internal Server Error'); } $response = ''; try { $response = \CMF::getCustomErrorResponse(\Lang::get("site.errors.http.500", array('resource' => 'page'), \Lang::get("site.errors.http.default", array('resource' => 'page'), 'Please contact the website administrator'))); } catch (\Exception $e) { $response = \View::forge('errors' . DS . 'production'); } exit($response); }
/** inheritdoc */ public static function displayForm($value, &$settings, $model) { $include_label = isset($settings['label']) ? $settings['label'] : true; $target_class = $settings['mapping']['targetEntity']; if (is_null($value) || !$value instanceof $target_class) { $value = new $target_class(); } // Show a simple alias form if the input var is set if (\Input::param('alias', false) !== false) { $linkValue = array(); if (!empty($value)) { $linkValue['href'] = $value->isExternal() ? $value->url : strval($value->id); $linkValue['external'] = $value->isExternal(); } return \CMF\Field\Object\Link::displayForm($linkValue, $settings, $model); } $model_class = get_class($model); $errors = $model->getErrorsForField($settings['mapping']['fieldName']); $has_errors = count($errors) > 0; $attributes = array('class' => 'field-type-url controls control-group' . ($has_errors ? ' error' : '')); $slug_name = $settings['mapping']['fieldName'] . '[slug]'; $label_text = $settings['title'] . ($has_errors ? ' - ' . $errors[0] : ''); if (\CMF::$lang_enabled && !\CMF::langIsDefault()) { if (!$value->hasTranslation('slug')) { $attributes['class'] .= ' no-translation'; $label_text = '<img class="lang-flag" src="' . \Uri::create('/admin/assets/img/lang/' . \CMF::defaultLang() . '.png') . '" /> ' . $label_text; } else { $label_text = '<img class="lang-flag" src="' . \Uri::create('/admin/assets/img/lang/' . \CMF::lang() . '.png') . '" /> ' . $label_text; } } $keep_updated_setting = 'settings[' . $settings['mapping']['fieldName'] . '][keep_updated]'; $keep_updated = \Form::hidden($keep_updated_setting, '0', array()) . html_tag('label', array('class' => 'checkbox keep-updated'), \Form::checkbox($keep_updated_setting, '1', \Arr::get($settings, 'keep_updated', true), array()) . strtolower(\Lang::get('admin.common.auto_update'))); $input = \Form::input($slug_name, $value->slug, array('class' => 'input-xlarge', 'data-copy-from' => implode(',', $model_class::slugFields()))); $label = !$include_label ? '' : html_tag('label', array('class' => 'item-label', 'for' => $slug_name), $label_text) . $keep_updated . html_tag('div', array('class' => 'clear'), ' '); $prefix = $value->prefix; $prepend = html_tag('span', array('class' => 'add-on'), empty($prefix) ? '/' : $prefix); $input = html_tag('div', array('class' => 'input-prepend'), $prepend . $input); $clear = '<div class="clear"><!-- --></div>'; if (isset($settings['wrap']) && $settings['wrap'] === false) { return $label . $input; } return html_tag('div', $attributes, $label . $input) . $clear; }
/** @inheritdoc */ public static function displayForm($value, &$settings, $model) { if (!is_array($value)) { $value = array('src' => $value); } $metadata = $model->metadata(); $settings = static::settings($settings); $settings['label'] = isset($settings['label']) ? $settings['label'] : true; $settings['required'] = isset($settings['required']) ? $settings['required'] : false; $settings['errors'] = $model->getErrorsForField($settings['mapping']['fieldName']); $settings['has_errors'] = count($settings['errors']) > 0; $settings['model'] = $metadata->name; $preview_value = isset($value) && isset($value['src']) ? str_replace($settings['path'], '', $value['src']) : ''; $content = strval(\View::forge('admin/fields/file.twig', array('settings' => $settings, 'value' => $value, 'preview_value' => $preview_value), false)); $attributes = array('class' => 'field-type-file file controls control-group' . ($settings['has_errors'] ? ' error' : ''), 'data-field-name' => $settings['mapping']['fieldName'], 'id' => 'field_' . \CMF::slug($settings['mapping']['fieldName'])); if (!(isset($settings['wrap']) && $settings['wrap'] === false)) { $content = html_tag('div', $attributes, $content); } return array('content' => $content, 'widget' => false, 'assets' => array(), 'js_data' => $settings); }
protected function processNodes(&$nodes, $uri, $level = 1, $label = 'level', $type = null) { $hasActive = false; foreach ($nodes as &$node) { $node['url'] = \CMF::link($node['url']); $node['active'] = ltrim($node['url'], "/") == ltrim($uri, "/"); $node['parent_active'] = false; if (isset($node['type'])) { $node['type'] = \Inflector::classify($node['type']); } else { if (!is_null($type)) { $node['type'] = $type; } } if (isset($node['__children']) && count($node['__children']) > 0) { $newlevel = $level + 1; $node['parent_active'] = $this->processNodes($node['__children'], $uri, $newlevel, $label, $type); if ($node['active'] || $node['parent_active']) { $levelid = $label ? $label . '_level' . $newlevel : 'level' . $newlevel; $parent = $node; unset($parent['__children']); if ($node['parent_active'] && $node['active']) { $node['active'] = false; } $parent = array($parent); $this->{$levelid} = array_merge($parent, $node['__children']); } } if ($node['parent_active'] || $node['active']) { $node['parent_active'] = $hasActive = true; $crumbs_label = $label ? $label . '_crumbs' : 'crumbs'; $crumbs = $this->{$crumbs_label}; $crumbs[$level - 1] = $node; $this->{$crumbs_label} = $crumbs; } } return $hasActive; }
public static function shutdown() { if (count(static::$to_save) > 0) { $groups = static::$to_save; $output = array(); foreach ($groups as $group) { $lft_db = static::load("{$group}.db", $group, \CMF::lang(), true, true); $rgt_db = static::load("{$group}.db", $group, static::$fallback[0], true, true); $lft = \Arr::get(static::$lines, \CMF::lang() . '.' . $group, array()); $rgt = \Arr::get(static::$lines, static::$fallback[0] . '.' . $group, array()); $lft = \Arr::merge($lft_db, $lft); $rgt = \Arr::merge($rgt_db, $rgt); foreach ($rgt as $key => $phrase) { if (!isset($lft[$key])) { $lft[$key] = $phrase; } } foreach ($lft as $key => $phrase) { if (!isset($rgt[$key])) { $rgt[$key] = $phrase; } } static::save("{$group}.db", $lft, \CMF::lang()); static::save("{$group}.db", $rgt, static::$fallback[0]); } exit; } }
/** * Tries to render the error response from a custom template, falling back to the default one */ public function response() { return \CMF::getCustomErrorResponse($this->getMessage(), $this->getCode()); }
public function __toString() { return \CMF::link(strval($this->url)); }
public static function getOptions(&$settings, $model, $html = false) { $allow_empty = isset($settings['mapping']['nullable']) && $settings['mapping']['nullable'] && !(isset($settings['required']) && $settings['required']); if (static::$options !== null && is_array(static::$options)) { return $allow_empty ? array('' => '') + static::$options : static::$options; } $options = array(); $target_class = 'CMF\\Model\\URL'; $filters = \Arr::get($settings, 'filters', array()); $tree_types = array(); $types = $target_class::select('item.type')->distinct()->where('item.item_id IS NOT NULL')->orderBy('item.type', 'ASC'); // Allow certain types $allow_types = \Arr::get($settings, 'allow_types', array()); if (count($allow_types) > 0) { $types->where('item.type IN(?1)')->setParameter(1, $allow_types); } else { // Exclude certain types $exclude_types = \Arr::get($settings, 'exclude_types', array('Model_Page_Home')); if (count($exclude_types) > 0) { $types->where('item.type NOT IN(?1)')->setParameter(1, $exclude_types); } } // Exclude / include modules $exclude_modules = \Arr::get($settings, 'exclude_modules', array()); $allow_modules = \Arr::get($settings, 'allow_modules', array()); $types = $types->getQuery()->getScalarResult(); foreach ($types as $type) { $type = $type['type']; if (!class_exists($type)) { continue; } $metadata = $type::metadata(); $root_class = $metadata->rootEntityName; $module = $type::getModule(); $moduleTitle = \CMF::moduleTitle($module); // Exclude / include modules if (count($allow_modules) > 0 && !in_array($module, $allow_modules)) { continue; } else { if (in_array($module, $exclude_modules)) { continue; } } if (isset($root_class)) { $type = $root_class; } $name = $type::_static() ? $moduleTitle : $moduleTitle . ' ' . $type::plural(); if (isset($options[$name])) { continue; } $group = \Arr::get($options, $name, array()); $repository = \D::manager()->getRepository($type); $prop = property_exists('menu_title', $type) ? 'menu_title' : 'title'; if ($repository instanceof \Gedmo\Tree\Entity\Repository\NestedTreeRepository && !in_array($name, $tree_types)) { $tree_types[] = $name; // Put in the tree data... $query = $type::select('item, url')->leftJoin('item.url', 'url')->where('item.lvl > 0')->andWhere('url.alias is NULL'); if (count($filters) > 0) { foreach ($filters as $filter) { $query = $query->andWhere('item.' . $filter); } } $tree = $query->orderBy('item.root, item.lft', 'ASC')->getQuery(); // Set the query hint if multi lingual! if (\CMF\Doctrine\Extensions\Translatable::enabled()) { $tree->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker'); } $tree = $tree->getArrayResult(); $tree = $repository->buildTree($tree, array()); $options[$name] = static::buildTreeOptions($tree, $prop, array()); continue; } $items = $type::select("item.id, item.{$prop}, url.url, url.id url_id, alias.id alias_id")->where('url.alias is NULL')->leftJoin('item.url', 'url')->leftJoin('url.alias', 'alias')->orderBy("item.{$prop}", "ASC")->getQuery(); // Set the query hint if multi lingual! if (\CMF\Doctrine\Extensions\Translatable::enabled()) { $items->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker'); } $items = $items->getArrayResult(); if (is_array($items) && count($items) > 0) { foreach ($items as $item) { if (empty($item['url_id'])) { continue; } $group[strval($item['url_id'])] = $item[$prop]; } $options[$name] = $group; } } foreach ($options as $group_name => &$group_value) { if (is_array($group_value) && !in_array($group_name, $tree_types)) { uasort($group_value, function ($a, $b) { return strcmp(strtolower($a), strtolower($b)); }); } } uksort($options, function ($a, $b) { return strcmp(strtolower($a), strtolower($b)); }); static::$options = $options; return $allow_empty ? array('' => '') + $options : $options; }
\Config::set('security.uri_filter', array_merge(array('\\Admin::module_url_filter'), \Config::get('security.uri_filter'))); } else { if (\Config::get('cmf.module_urls', false) !== false) { \Config::set('security.uri_filter', array_merge(array('\\CMF::module_url_filter'), \Config::get('security.uri_filter'))); } } // Load up the required packages Package::load(array('email', 'parser')); // Override some external classes Autoloader::add_core_namespace('CMF\\Core', true); Autoloader::add_classes(array('CMF\\Core\\View_Twig' => __DIR__ . '/classes/CMF/Core/View_Twig.php', 'CMF\\Core\\Image_Driver' => __DIR__ . '/classes/CMF/Core/Image_Driver.php', 'CMF\\Core\\Lang' => __DIR__ . '/classes/CMF/Core/Lang.php', 'CMF\\Core\\Format' => __DIR__ . '/classes/CMF/Core/Format.php', 'CMF\\Core\\Error' => __DIR__ . '/classes/CMF/Core/Error.php', 'CMF\\Core\\HttpException' => __DIR__ . '/classes/CMF/Core/HttpException.php')); // Sort out the language \Lang::load('errors', true); \Lang::load('admin', true); \Lang::load('site', true); $lang = \CMF::lang(); // Quick and easy profiling using 'debug' in the query string if (isset($_GET['debug']) && !\Fuel::$profiling) { \Fuel::$profiling = true; \Profiler::init(); \Config::load('db', true); \Config::set('db.default.profiling', true); } // Listen for events at the beginning of the request for caching \Event::register('controller_started', 'CMF\\Cache::start'); // Add CMF's modules directory so it's modules can be autoloaded $module_paths = Config::get('module_paths'); $module_paths[] = CMFPATH . 'modules/'; Config::set('module_paths', $module_paths); if ($isAdmin) { \Admin::initialize();
/** * Set up the array of "child" languages which need to be updated by others */ protected function initLanguages() { // Only need to do this once! if ($this->childLanguages !== null) { return; } $this->childLanguages = \CMF\Model\Language::select('item', 'item', 'item.code')->where('update_from IS NOT NULL')->andWhere('update_from.code = :code')->andWhere('item.visible = true')->leftJoin('item.update_from', 'update_from')->setParameter('code', \CMF::lang())->getQuery()->getResult(); }
/** * Duplicate an item */ public function action_duplicate() { $class_name = $this->model; $message = \Lang::get('admin.messages.item_duplicate_success', array('resource' => $class_name::singular())); $success = true; try { $duplicate = \CMF::duplicateItem($class_name, $this->id); } catch (\Exception $e) { $message = $e->getMessage(); $success = false; } $output = array('success' => $success, 'message' => $message); if (!empty($duplicate)) { $output['id'] = $duplicate->id; $output['label'] = $duplicate->display(); } return $output; }
/** * Tries to render an error response from a custom template, falling back to the default one */ public static function getCustomErrorResponse($message = null, $code = 500, $default_template = 'errors/http.twig') { $view = null; $template = 'errors/' . $code . '.twig'; $status = \Arr::get(\Response::$statuses, $code, 'Internal Server Error'); $data = array('code' => $code, 'status' => $status, 'model' => null, 'message' => $message ? $message : \Lang::get("site.errors.http.{$code}", array('resource' => 'page'), \Lang::get("site.errors.http.default", array('resource' => 'page'), $status))); // First try the specific error page try { if ($viewClass = \CMF::hasViewModel($template)) { $view = new $viewClass('view', false, $template); } else { $viewClass = ucfirst(\CMF::$module) . '\\View_Base'; if (!class_exists($viewClass)) { $viewClass = '\\View_Base'; } $view = new $viewClass('view', false, $template); } $view->set($data); $view = $view->render(); } catch (\Exception $e) { $view = null; } // Then try the provided default template if (!$view) { try { if ($viewClass = \CMF::hasViewModel($default_template)) { $view = new $viewClass('view', false, $default_template); } else { $viewClass = ucfirst(\CMF::$module) . '\\View_Base'; if (!class_exists($viewClass)) { $viewClass = '\\View_Base'; } $view = new $viewClass('view', false, $default_template); } $view->set($data); $view = $view->render(); } catch (\Exception $e) { $view = null; } } // Then try the above, without the view models if (!$view) { try { $view = \View::forge($template, $data); } catch (\Exception $e) { $view = null; } } if (!$view) { try { $view = \View::forge($default_template, $data); } catch (\Exception $e) { $view = null; } } // If all the above hasn't worked, we can always fall back to the system template! if (!$view) { $view = \View::forge('errors/http', $data); } return new \Response($view, $code); }
/** * Returns a new duplicate copy of the entity */ public function duplicate($flushdb = true, &$translations = array(), &$entityMap = array(), $excludeFields = array()) { $metadata = $this->metadata(); $class = $metadata->getName(); $fieldNames = $metadata->getFieldNames(); $associationNames = $metadata->getAssociationNames(); $duplicate = new $class(); $isTree = $this->isTreeNode(); if ($class::_static()) { throw new \Exception($class::singular() . ' is a static type and cannot be duplicated'); } // Copy field names across foreach ($fieldNames as $fieldName) { if (in_array($fieldName, $excludeFields)) { continue; } $value = $this->get($fieldName); $duplicate->set($fieldName, $value); } // Copy associations across foreach ($associationNames as $associationName) { if (in_array($associationName, $excludeFields)) { continue; } $associationMapping = $metadata->getAssociationMapping($associationName); $value = $this->get($associationName); $shouldCopy = $associationMapping['orphanRemoval'] || $associationMapping['isCascadeRemove']; $isTreeChildren = $isTree && $associationName == 'children'; $targetPropName = $associationMapping['isOwningSide'] ? @$associationMapping['inversedBy'] : @$associationMapping['mappedBy']; if (!empty($value) && ($shouldCopy || $isTreeChildren)) { if ($metadata->isCollectionValuedAssociation($associationName)) { $duplicateCollection = array(); foreach ($value as $item) { $itemClass = $item->metadata()->name; if (!$itemClass::_static()) { $duplicateItem = $item->duplicate(false, $translations, $entityMap, array($targetPropName)); if (!empty($duplicateItem)) { $duplicateCollection[] = $duplicateItem; } } } $value = $duplicateCollection; } else { $itemClass = $value->metadata()->name; if (!$itemClass::_static()) { $value = $value->duplicate(false, $translations, $entityMap, array($targetPropName)); } else { $value = null; } } } $duplicate->set($associationName, $value); } if (!$flushdb) { \D::manager()->persist($duplicate); } // If languages are enabled, add its translations to the array reference using the new oid if ($this->id && \CMF::langEnabled()) { $oid = spl_object_hash($duplicate); $entityMap[$oid] = $duplicate; if (!isset($translations[$oid])) { $translations[$oid] = \DB::query("SELECT * FROM ext_translations WHERE object_class = '{$metadata->rootEntityName}' AND foreign_key = '{$this->id}'")->execute()->as_array(); } } if ($flushdb) { // Persist the item if ($isTree) { $class::repository()->persistAsNextSiblingOf($duplicate, $this); } else { \D::manager()->persist($duplicate); } $displayField = $this->findFieldUsedInDisplay(); if (!empty($displayField)) { $duplicate->setUniqueValueForField($displayField); } \D::manager()->flush(); // Add translations after all the entities have been committed to the db if (!empty($translations)) { foreach ($translations as $objectHash => $objectTranslations) { $entity = isset($entityMap[$objectHash]) ? $entityMap[$objectHash] : null; if (empty($entity) || empty($entity->id) || empty($objectTranslations)) { continue; } $cols = null; $qb = \DB::insert('ext_translations'); foreach ($objectTranslations as $translation) { unset($translation['id']); $translation['foreign_key'] = strval($entity->id); if (is_null($cols)) { $cols = array_keys($translation); $qb->columns($cols); } // Insert the new translations $qb->values($translation); } $qb->execute(); } } try { if (is_subclass_of($class, 'CMF\\Model\\Node')) { $repo = \D::manager()->getRepository($class); $repo->recover(); \D::manager()->flush(); } } catch (\Exception $e) { } } return $duplicate; }
/** inheritdoc */ public static function displayForm($value, &$settings, $model) { $settings = static::settings($settings); $target_class = $settings['mapping']['targetEntity']; $target_metadata = $target_class::metadata(); // Get the array of possible types $types = array($target_class); $exclude_types = array(); if (count($target_metadata->subClasses) > 0) { if ($target_class::superclass() === true) { $types = array(); } $types = array_merge($types, $target_metadata->subClasses); } if (isset($value) && $value instanceof \Doctrine\Common\Collections\Collection) { $value = $value->toArray(); } else { if (!is_array($value)) { $value = array(); } } $target_field = $settings['mapping']['isOwningSide'] === true ? $settings['mapping']['inversedBy'] : $settings['mapping']['mappedBy']; $sortable = $target_class::sortable() && isset($settings['mapping']['orderBy']) && isset($settings['mapping']['orderBy']['pos']) && $settings['mapping']['orderBy']['pos'] == 'ASC'; $sort_group = $target_class::sortGroup(); $image_field = $settings['image_field']; // Detect an image field if one hasn't been specified if ($image_field === null) { foreach ($target_metadata->fieldMappings as $field_name => $field_mapping) { if ($field_mapping['type'] == 'image') { $image_field = $field_name; break; } } } $settings['image_field'] = $image_field; // If the target isn't grouped by this relationship, we need to save all the positions at once... $save_all = $sort_group != $target_field; $exclude = array($target_field); $hidden_fields = array(); if ($sortable) { $hidden_fields['pos'] = 0; } // The forms from which we'll render out each row, but also the blank forms for the 'new item' templates $form_templates = array(); $js_data = array(); $target_tables = array(); $templates_content = array(); $assets = array(); $add_types = array(); foreach ($types as $type) { $metadata = $type::metadata(); $prefix = '__TEMP__' . $settings['mapping']['fieldName'] . '[__NUM__]'; $form_templates[$type] = new ModelForm($metadata, new $type(), $prefix, $hidden_fields, $exclude, true); $target_tables[$type] = $metadata->table['name']; $templates_content[$type] = array('hidden_fields' => $form_templates[$type]->hidden_fields, 'fields' => $form_templates[$type]->getFieldContent(), 'icon' => $type::icon(), 'singular' => $type::singular(), 'prefix' => $prefix); $add_types[] = array('type' => $type, 'singular' => $type::singular(), 'plural' => $type::plural(), 'icon' => $type::icon()); foreach ($form_templates[$type]->js_field_settings as $key => $js_settings) { if (!isset($js_data[$key])) { $js_data[$key] = $js_settings; } } $assets = \Arr::merge($assets, $form_templates[$type]->assets); } // Loop through and get each row from the form $rows = array(); foreach ($value as $num => $model) { // Get the class of this item $type = \CMF::getClass($model); if (!isset($form_templates[$type])) { continue; } $form_template = $form_templates[$type]; $prefix = $settings['mapping']['fieldName'] . '[' . $num . ']'; $row = $form_template->getFields($model, $prefix); $row['_icon_'] = $type::icon(); $row['_title_'] = $model->display(); $row['_model_'] = $model; $row['hidden_fields']['id'] = \Form::hidden($prefix . '[id]', $model->id, array('class' => 'item-id')); $row['hidden_fields']['__type__'] = \Form::hidden($prefix . '[__type__]', $type); $rows[] = $row; $js_data = array_merge($js_data, $row['js_field_settings']); } $js_data[$settings['mapping']['fieldName']] = array('target_tables' => $target_tables, 'target_class' => $settings['mapping']['targetEntity'], 'add_types' => $add_types, 'save_all' => $save_all, 'sortable' => $sortable, 'image_field' => $image_field); return array('assets' => $assets, 'content' => strval(\View::forge('admin/fields/collection/gallery-inline.twig', array('settings' => $settings, 'add_types' => $add_types, 'icon' => $target_class::icon(), 'singular' => $target_class::singular(), 'plural' => $target_class::plural(), 'rows' => $rows, 'templates' => $templates_content, 'forms' => $form_templates, 'sortable' => $sortable), false)), 'widget' => false, 'widget_class' => '', 'widget_icon' => $target_class::icon(), 'js_data' => $js_data, 'merge_data' => true); }
public function showTranslationStatus($model) { return \CMF::$lang_enabled && !\CMF::langIsDefault() && isset($this->settings['mapping']['columnName']) && $model->isTranslatable($this->settings['mapping']['columnName']); }
/** * Renders the item list (the table view) * @param string $table_name * @return void */ public function action_index($table_name, $tab_id = null) { $class_name = \Admin::getClassForTable($table_name); if ($class_name === false) { return $this->customPageOr404(array($table_name, $tab_id), "type"); } // Redirect straight to the edit page if the item is static if ($class_name::_static() === true) { $static_item = $class_name::select('item')->setMaxResults(1)->getQuery()->getResult(); if (count($static_item) > 0) { $static_item = $static_item[0]; \Response::redirect("/admin/{$table_name}/" . $static_item->id . "/edit", 'location'); } else { \Response::redirect("/admin/{$table_name}/create", 'location'); } } if (!\CMF\Auth::can('view', $class_name)) { return $this->show403('action_plural', array('action' => \Lang::get('admin.verbs.view'), 'resource' => strtolower($class_name::plural()))); } // Here's where we catch special types, eg tree nodes. These can now be rendered using a special template if (is_subclass_of($class_name, 'CMF\\Model\\Node')) { return $this->treeView($class_name); } // Get permissions $can_create = \CMF\Auth::can('create', $class_name); $can_edit = \CMF\Auth::can('edit', $class_name); $can_delete = \CMF\Auth::can('delete', $class_name); $can_manage = \CMF\Auth::can(array('view', 'edit'), 'CMF\\Model\\Permission'); // Get the data for the list $metadata = $class_name::metadata(); $query_fields = $class_name::query_fields(); $pagination = $class_name::pagination(); $sortable = $class_name::sortable(); $per_page = $class_name::per_page(); $sort_group = is_callable($class_name . '::sortGroup') ? $class_name::sortGroup() : null; $sort_process = $class_name::sortProcess(); $excluded_ids = array(); $fields = \Admin::getFieldSettings($class_name); $list_tabs = $class_name::listTabs(); $list_fields = $class_name::listFields(); $list_filters = array(); if (empty($list_fields)) { $list_fields = array_keys($fields); } $columns = array(); $joins = array(); $methods = array(); // See if we have any imported models // $importedIds = $class_name::getImportedIds(); // if (count($importedIds)) { // if (!count($list_tabs)) { // $list_tabs['main'] = array( // 'title' => 'Main', // 'filters' => array('id NOT IN ('.implode(',',$importedIds).')') // ); // } // $list_tabs['imported'] = array( // 'title' => 'Imported ('.count($importedIds).')', // 'filters' => array('id IN ('.implode(',',$importedIds).')') // ); // } // Find out the tab we're on if (count($list_tabs) > 0) { $this->default_tab = key($list_tabs); if ($tab_id === null || !isset($list_tabs[$tab_id])) { $tab_id = $this->default_tab; } $tab = \Arr::get($list_tabs, $tab_id, array()); $list_fields = \Arr::get($tab, 'fields', $list_fields); $list_filters = \Arr::get($tab, 'filters', $list_filters); $this->current_tab = $tab_id; } // Create static items \Admin::createStaticInstances($metadata); // See if the list order has been set in the session. If not, try and use the model's default order $order = \Session::get($metadata->table['name'] . ".list.order", null); if (is_null($order)) { $order = $class_name::order(); } else { $order = $order + $class_name::order(); } // Start the query builder... $qb = $class_name::select('item', 'item', 'item.id'); // Retrieve any custom joins from config on the model $manual_joins = $class_name::joins(); foreach ($manual_joins as $join_alias => $manual_join) { $qb->leftJoin($manual_join, $join_alias)->addSelect($join_alias); } // Add any joins to the query builder (prevents the query buildup that comes from accessing lazily loaded associations) foreach ($list_fields as $num => $field) { if ($field == 'id') { continue; } // If there is a dot notation try and locate the field if (strpos($field, ".") !== false) { $parts = explode(".", $field); $field_name = array_shift($parts); // If this dot notation refers to an association, we need to find the field data for the target type! if ($metadata->isSingleValuedAssociation($field_name)) { $target_class = $metadata->getAssociationTargetClass($field_name); $target_fields = \Admin::getFieldSettings($target_class); foreach ($target_fields as $target_field => $target_field_settings) { $target_field_settings['title'] = $target_class::singular() . ' ' . $target_field_settings['title']; $fields[$field_name . '.' . $target_field] = $target_field_settings; } } } else { $field_name = $field; } // This could be a method on the model if (!isset($fields[$field])) { if (array_key_exists($field_name, $manual_joins)) { $join_heading = \Inflector::humanize(\Inflector::underscore($field_name)); $parts = explode(".", $field); if (count($parts) == 2) { $field_colons = implode(':', $parts); if (isset($order[$field_colons])) { $dir = strtolower($order[$field_colons]); $rev = $dir == 'asc' ? 'desc' : 'asc'; $arrows = html_tag('span', array('class' => 'arrow-down'), '▼') . html_tag('span', array('class' => 'arrow-up'), '▲'); $verbose = $dir == 'asc' ? 'descending' : 'ascending'; $join_heading = html_tag('a', array('href' => \Uri::create("/admin/{$table_name}/list/order?{$field_colons}={$rev}"), 'class' => 'sort-link ' . $dir, 'title' => 'Sort by ' . $join_heading . ' ' . $verbose), $join_heading . ' ' . $arrows); } else { $join_heading = html_tag('a', array('href' => \Uri::create("/admin/{$table_name}/list/order?{$field_colons}=asc"), 'class' => 'sort-link', 'title' => 'Sort by ' . $join_heading . ' ascending'), $join_heading); } } $columns[] = array('num' => $num, 'type' => 'join', 'join' => $parts[0], 'name' => count($parts) > 1 ? $parts[1] : 'display', 'heading' => $join_heading); } else { if (method_exists($class_name, $field_name)) { $column = array('num' => $num, 'type' => 'method', 'name' => $field_name, 'heading' => \Inflector::humanize(\Inflector::underscore($field_name))); /* if (isset($order[$field_name])) { $dir = strtolower($order[$field_name]); $rev = ($dir == 'asc') ? 'desc' : 'asc'; $arrows = html_tag('span', array( 'class' => 'arrow-down' ), '▼').html_tag('span', array( 'class' => 'arrow-up' ), '▲'); $verbose = ($dir == 'asc') ? 'descending' : 'ascending'; $column['heading'] = html_tag('a', array( 'href' => \Uri::create("/admin/$table_name/list/order?$field_name=$rev"), 'class' => 'sort-link '.$dir, 'title' => 'Sort by '.$column['heading'].' '.$verbose ), $column['heading'].' '.$arrows); } else { $column['heading'] = html_tag('a', array( 'href' => \Uri::create("/admin/$table_name/list/order?$field_name=asc"), 'class' => 'sort-link', 'title' => 'Sort by '.$column['heading'].' ascending' ), $column['heading']); } */ $methods[] = $field_name; $columns[] = $column; } } continue; } if ($metadata->isSingleValuedAssociation($field_name) && !in_array($field_name, $joins) && !array_key_exists($field_name, $manual_joins)) { $qb->leftJoin('item.' . $field_name, $field_name)->addSelect($field_name); $joins[] = $field_name; } else { if ($metadata->isCollectionValuedAssociation($field_name) && !in_array($field_name, $joins) && !array_key_exists($field_name, $manual_joins)) { $qb->leftJoin('item.' . $field_name, $field_name)->addSelect($field_name); $joins[] = $field_name; } } // Get the field class and type $field_class = $fields[$field]['field']; $field_type = $field_class::type(); $column = array('name' => $field, 'type' => $field_type); if (!$sortable) { $field_colons = str_replace('.', ':', $field); if (isset($order[$field_colons])) { $dir = strtolower($order[$field_colons]); $rev = $dir == 'asc' ? 'desc' : 'asc'; $arrows = html_tag('span', array('class' => 'arrow-down'), '▼') . html_tag('span', array('class' => 'arrow-up'), '▲'); $verbose = $dir == 'asc' ? 'descending' : 'ascending'; $column['heading'] = html_tag('a', array('href' => \Uri::create("/admin/{$table_name}/list/order?{$field_colons}={$rev}"), 'class' => 'sort-link ' . $dir, 'title' => 'Sort by ' . $fields[$field]['title'] . ' ' . $verbose), $fields[$field]['title'] . ' ' . $arrows); } else { $column['heading'] = html_tag('a', array('href' => \Uri::create("/admin/{$table_name}/list/order?{$field_colons}=asc"), 'class' => 'sort-link', 'title' => 'Sort by ' . $fields[$field]['title'] . ' ascending'), $fields[$field]['title']); } } else { $column['heading'] = $fields[$field]['title']; } $columns[] = $column; } // Add dropdown list filters $filter_by = $class_name::list_filters(); if (is_array($filter_by) && count($filter_by) > 0) { $filters = array(); foreach ($filter_by as $filter_field) { if ($metadata->hasAssociation($filter_field)) { $filter_class = $metadata->getAssociationTargetClass($filter_field); $filter_name = \Arr::get($fields, "{$filter_field}.title", ''); $filter_options = array('' => 'All ' . $filter_class::plural()) + $filter_class::options(); $filter_val = \Input::get($filter_field); $filter_is_tree = is_subclass_of($filter_class, 'CMF\\Model\\Node'); if (!empty($filter_val) && $filter_is_tree && ($filterEntity = $filter_class::find($filter_val))) { $filter_val = $filterEntity->getChildrenIds(false, null, 'ASC', true); } if (empty($filter_val) && $filter_field == $sort_group) { $sortable = false; } $filters[$filter_field] = array('label' => 'Show ' . strtolower($filter_name) . ':', 'options' => $filter_options); if (!in_array($filter_field, $joins) && !array_key_exists($filter_field, $manual_joins)) { $qb->leftJoin('item.' . $filter_field, $filter_field)->addSelect($filter_field); $joins[] = $filter_field; } if (!empty($filter_val)) { $paramName = $filter_name . 'filter'; if (is_array($filter_val)) { if (count($filter_val) > 1 && $filter_field == $sort_group) { $sortable = false; } $qb->andWhere("{$filter_field} IN(:{$paramName})"); } else { $qb->andWhere("{$filter_field} = :{$paramName}"); } $qb->setParameter($paramName, $filter_val); } } } $this->filters = $filters; } // Add list filters foreach ($list_filters as $num => $filter) { $filter_str = is_array($filter) ? 'item.' . implode(' OR item.', $filter) : 'item.' . $filter; $qb->andWhere($filter_str); } if (!empty($query_fields) && count($query_fields) > 0) { //if query string then search the fields provided $this->searchable = true; $query = \Input::get('query'); $this->query = $query; if ($query) { $query_parts = array_map('trim', explode(' ', $query)); $query_str = array(); $query_val = array(); $x = 0; foreach ($query_fields as $field) { foreach ($query_parts as $query_part) { $query_str[$x] = "item." . $field . " LIKE ?" . $x; $query_val[$x] = "%{$query_part}%"; $x++; } } $qb->andWhere(implode(' OR ', $query_str)); foreach ($query_val as $key => $val) { $qb->setParameter($key, $val); } } } if (\CMF::$lang_enabled && !\CMF::langIsDefault() && $class_name::langEnabled()) { array_unshift($columns, array('name' => '', 'type' => 'lang', 'heading' => '')); } // Make the list drag and drop, if editing is possible if ($sortable && $can_edit) { $pagination = false; array_unshift($columns, array('name' => '', 'type' => 'handle', 'heading' => '')); } // Add the sortable ordering if ($sortable) { $has_group = !is_null($sort_group) && property_exists($class_name, $sort_group); if ($has_group) { if (!in_array($sort_group, $joins)) { $qb->leftJoin('item.' . $sort_group, $sort_group)->addSelect($sort_group); $joins[] = $sort_group; } if ($metadata->hasAssociation($sort_group)) { $assoc_class = $metadata->getAssociationTargetClass($sort_group); $assoc_field = property_exists($assoc_class, 'name') ? 'name' : (property_exists($assoc_class, 'title') ? 'title' : 'id'); $qb->addOrderBy("{$sort_group}.{$assoc_field}", 'ASC'); } else { $qb->addOrderBy("item.{$sort_group}", 'ASC'); } } $qb->addOrderBy('item.pos', 'ASC'); } else { // Add the ordering to the query builder foreach ($order as $field => $direction) { if (in_array($field, $methods)) { continue; } $field_name = $field; $assoc_field = 'title'; // If there is a dot notation (or colon) try and locate the field if (strpos($field, ".") !== false) { $parts = explode(".", $field); $field_name = array_shift($parts); $assoc_field = array_shift($parts); } else { if (strpos($field, ":") !== false) { $parts = explode(":", $field); $field_name = array_shift($parts); $assoc_field = array_shift($parts); } } if (array_key_exists($field_name, $manual_joins)) { $qb->addOrderBy("{$field_name}.{$assoc_field}", $direction); } else { if ($metadata->hasAssociation($field_name)) { $assoc_class = $metadata->getAssociationTargetClass($field_name); if (!property_exists($assoc_class, $assoc_field)) { $assoc_field = property_exists($assoc_class, 'title') ? 'title' : 'id'; } $qb->addOrderBy("{$field_name}.{$assoc_field}", $direction); } else { $qb->addOrderBy("item.{$field_name}", $direction); } } } } if ($pagination) { /* PAGINATION */ $countquery = clone $qb; $countPaginator = new Paginator($countquery, true); $count = $countPaginator->count(); $config = array('pagination_url' => 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], 'total_items' => $count, 'per_page' => $per_page, 'uri_segment' => 'p', 'wrapper' => '<div class="pagination"><ul>{pagination}</ul></div>', 'first' => '<li class="first">{link}</li>', 'previous' => '<li class="prev">{link}</i>', 'previous-inactive' => '', 'regular' => '<li>{link}</li>', 'active' => '<li class="active">{link}</li>', 'next' => '<li class="next">{link}</li>', 'next-inactive' => '', 'previous-marker' => '< Prev', 'next-marker' => 'Next >'); $pagination = \Pagination::forge('default', $config); $qb->setMaxResults($pagination->per_page); $qb->setFirstResult($pagination->offset); $this->pagination = $pagination->render(); $this->per_page = $per_page; $this->page_count = ceil($count / $per_page); $this->total_items = $count; $this->current_page = \Input::param('p', 1); $rows = new Paginator($qb, true); $ids = array(); foreach ($rows as $prow) { $ids[] = $prow->id; } reset($ids); } else { $this->pagination = null; $rows = $qb->getQuery()->getResult(); $ids = array_keys($rows); } // Another pass at the ordering for methods /* foreach ($order as $field => $direction) { if (!in_array($field, $methods)) continue; if ($direction == 'asc') { uasort($rows, function($a, $b) use($field) { return strcmp(strtolower($a->$field()), strtolower($b->$field())); }); } else { uasort($rows, function($a, $b) use($field) { return strcmp(strtolower($b->$field()), strtolower($a->$field())); }); } } */ // Item-specific permissions $user = \CMF\Auth::current_user(); $item_permissions = array(); if (!$user->super_user) { $user_roles = $user->roles->toArray(); $permissions = \CMF\Model\Permission::select('item.id, item.action, item.resource, item.item_id')->leftJoin('item.roles', 'roles')->where("item.resource = '{$class_name}'"); if (count($ids) > 0) { $permissions->andWhere("item.item_id IN(?1)")->setParameter(1, $ids); } if (count($user_roles) > 0) { $permissions->andWhere("roles IN (?2)")->setParameter(2, $user->roles->toArray()); } $permissions = $permissions->getQuery()->getArrayResult(); foreach ($permissions as $permission) { $item_actions = isset($item_permissions[$permission['item_id']]) ? $item_permissions[$permission['item_id']] : array(); $item_actions[] = $permission['action']; $item_permissions[$permission['item_id']] = $item_actions; } foreach ($item_permissions as $item_id => $item_actions) { if (in_array('none', $item_actions) || count($item_actions) > 0 && !in_array('view', $item_actions)) { $excluded_ids[] = $item_id; } } } // Import actions $importMethods = $class_name::importMethods(); // Actions $this->actions = $class_name::actions(); \Admin::setCurrentClass($class_name); $this->class_lang_enabled = $class_name::langEnabled(); $this->plural = $class_name::plural(); $this->excluded_ids = $excluded_ids; $this->item_permissions = $item_permissions; $this->singular = $class_name::singular(); $this->icon = $class_name::icon(); $this->rows = $rows; $this->columns = $columns; $this->fields = $fields; $this->table_name = $metadata->table['name']; $this->template = 'admin/item/list.twig'; $this->superlock = $class_name::superlock(); $this->sortable = $sortable && $can_edit; $this->sort_group = $sort_group; $this->tabs = $list_tabs; $this->sort_process = $sort_process; // Find all possible types that can be added $classes = array(); $classes[$class_name] = array('plural' => $this->plural, 'singular' => $this->singular, 'icon' => $this->icon, 'table_name' => $metadata->table['name'], 'can_create' => $can_create && $can_edit, 'can_edit' => $can_edit, 'can_delete' => $can_delete, 'superclass' => $class_name::superclass()); foreach ($metadata->subClasses as $sub_class) { $subclass_metadata = $sub_class::metadata(); if (($subclass_cancreate = \CMF\Auth::can('create', $sub_class)) && !$sub_class::_static()) { $classes[$sub_class] = array('superlock' => $sub_class::superlock(), 'plural' => $sub_class::plural(), 'singular' => $sub_class::singular(), 'icon' => $sub_class::icon(), 'table_name' => $subclass_metadata->table['name'], 'can_edit' => \CMF\Auth::can('edit', $sub_class), 'can_delete' => \CMF\Auth::can('delete', $sub_class), 'superclass' => false); } } $this->classes = $classes; // Permissions $this->can_create = $can_create && $can_edit; $this->can_edit = $can_edit; $this->can_delete = $can_delete; $this->can_manage = $can_manage; $this->can_import = !empty($importMethods) && $can_manage; // Add the stuff for JS $this->js['table_name'] = $metadata->table['name']; $this->js['plural'] = $this->plural; $this->js['singular'] = $this->singular; }
/** * Automatically locates the ViewModel for the configured template, unless a response has already been generated. * * @access public * @return Response */ public function after($response) { // If a response has been provided, just go with it if (!is_null($response)) { return $response; } if ($this->status == 404) { return $this->show404(); } // Get the model - this will have previously been found if (is_null($this->model)) { $this->model = \CMF::currentModel(); } if (!isset($this->template)) { // Try and find the template from the CMF... $this->template = \CMF::$template; } if (is_null($this->template)) { return $this->show404(); } // Determine whether the ViewModel class exists... if ($viewClass = \CMF::hasViewModel($this->template)) { $viewModel = new $viewClass('view', false, $this->template); $this->bindData($viewModel); return \Response::forge($viewModel, $this->status, $this->headers); } try { $viewClass = ucfirst(\CMF::$module) . '\\View_Base'; if (!class_exists($viewClass)) { $viewClass = '\\View_Base'; } $viewModel = new $viewClass('view', false, $this->template); $this->bindData($viewModel); return \Response::forge($viewModel, $this->status, $this->headers); } catch (\Exception $e) { return $this->show404("The template '" . $this->template . "' couldn't be found!"); } }
/** @inheritdoc */ public static function displayForm($value, &$settings, $model) { $settings = static::settings($settings); $include_label = isset($settings['label']) ? $settings['label'] : true; $required = isset($settings['required']) ? $settings['required'] : false; $errors = $model->getErrorsForField($settings['mapping']['fieldName']); $has_errors = count($errors) > 0; $input_attributes = isset($settings['input_attributes']) ? $settings['input_attributes'] : array('class' => 'input-xxlarge'); $options = \CMF::getOptions(get_class($model), \Arr::get($settings, 'mapping.columnName'), isset($settings['options']) ? $settings['options'] : array()); // Description? $description = isset($settings['description']) ? '<span class="help-block">' . $settings['description'] . '</span>' : ''; if (!empty($options) && !\Arr::is_assoc($options) && $settings['use_key'] !== true) { $options = array_combine($options, $options); } else { if (!empty($options)) { reset($options); $first = current($options); if (is_array($first) && isset($first['value'])) { $options = array_map(function ($option) { return $option['value']; }, $options); } } } if (@$settings['multiple']) { if (is_null($value) || empty($value)) { if (@$settings['default'] == 'all' && is_array($options)) { $value = array_keys($options); } } if (!is_array($value)) { $value = explode(',', $value); } $input_attributes['multiple'] = 'multiple'; } else { if (isset($settings['mapping']['nullable']) && $settings['mapping']['nullable'] && !(isset($settings['required']) && $settings['required']) && $settings['allow_empty']) { $options = array('' => '') + $options; } } // Transform the options into the right format foreach ($options as $key => $option) { if (is_array($option)) { $options[$key] = \Arr::get($option, 'title', $key); } } // Select2? if (is_array($settings['select2'])) { $settings['is_select2'] = true; $input_attributes['class'] .= ' input-xxlarge select2'; $settings['select2']['placeholder'] = 'click to select an option'; $label = !$include_label ? '' : \Form::label($settings['title'] . ($required ? ' *' : '') . ($has_errors ? ' - ' . $errors[0] : ''), $settings['mapping']['fieldName'], array('class' => 'item-label')); $input = \Form::select($settings['mapping']['fieldName'], $value, $options, $input_attributes); $content = $label . $description . $input; if (!(isset($settings['wrap']) && $settings['wrap'] === false)) { $content = html_tag('div', array('class' => 'controls control-group' . ($has_errors ? ' error' : '')), $content); } return array('content' => $content . html_tag('div', array(), ''), 'widget' => @$settings['widget'], 'assets' => array('css' => array('/admin/assets/select2/select2.css'), 'js' => array('/admin/assets/select2/select2.min.js', '/admin/assets/js/fields/select2.js')), 'js_data' => $settings['select2']); } if (!is_string($value)) { $value = strval($value); } $options = array_map('strip_tags', $options); $label = !$include_label ? '' : \Form::label($settings['title'] . ($required ? ' *' : '') . ($has_errors ? ' - ' . $errors[0] : ''), $settings['mapping']['fieldName'], array('class' => 'item-label')); $input = \Form::select($settings['mapping']['fieldName'], strval($value), $options, $input_attributes); if (isset($settings['wrap']) && $settings['wrap'] === false) { return $label . $input; } return html_tag('div', array('class' => 'controls control-group' . ($has_errors ? ' error' : '')), $label . $description . $input); }
/** * Given an ID, duplicates the form to edit an item. */ public function action_duplicate($table_name, $id = null) { // Find class name and metadata $class_name = \Admin::getClassForTable($table_name); if ($class_name === false) { return $this->show404(null, "type"); } // Set message etc $message = \Lang::get('admin.messages.item_duplicate_success', array('resource' => $class_name::singular())); $success = true; try { $duplicate = \CMF::duplicateItem($class_name, $id); } catch (\Exception $e) { $message = $e->getMessage(); $success = false; } // Send user back \Session::set_flash('main_alert', array('attributes' => array('class' => $success ? 'alert-success' : 'alert-danger'), 'msg' => $message)); $next = \Input::param('next', \Input::referrer("/admin/{$table_name}")); \Response::redirect($next); }
/** * Takes an entity and works out whether it has a relation to CMF's URL Model. If so, * it updates the properties of the associated URL object. * * @param object $entity * @param \Doctrine\ORM\EntityManager $em * @param \Doctrine\ORM\UnitOfWork|null $uow * @return void */ protected function process(&$entity, &$em, &$uow) { $entity_class = get_class($entity); $entity_namespace = trim(\CMF::slug(str_replace('\\', '/', \Inflector::get_namespace($entity_class))), '/'); $metadata = $em->getClassMetadata($entity_class); // Ignore URL entities themselves if ($metadata->name == 'CMF\\Model\\URL') { return; } $url_associations = $metadata->getAssociationsByTargetClass('CMF\\Model\\URL'); if (!empty($url_associations)) { // A bit hacky, but if this is a root tree item don't bother if (property_exists($entity, 'is_root') && $entity->is_root === true) { return; } $url_field = null; foreach ($url_associations as $key => $association) { if ($association['type'] == ClassMetadataInfo::ONE_TO_ONE && $association['orphanRemoval']) { $url_field = $key; break; } } if ($url_field == null) { return; } $settings = $entity->settings(); $url_settings = isset($settings[$url_field]) ? $settings[$url_field] : array(); $url_item = $entity->get($url_field); if ($new_url = is_null($url_item)) { $url_item = new \CMF\Model\URL(); } // Don't run if this is an alias... $alias = $url_item->alias; if (!is_null($alias) && !empty($alias)) { return; } // Don't run if this is an external link... if ($url_item->isExternal()) { return; } $prefix = $this->getPrefix($entity); $slug = ''; if (isset($url_settings['keep_updated']) && !$url_settings['keep_updated']) { $slug = \CMF::slug($url_item->slug); } else { $slug = $entity->urlSlug(); } $url = $prefix . $slug; if ($url != '/') { $url = rtrim($url, '/'); } $current_url = $url_item->url; $entity_id = $entity->id; $url_id = $url_item->get('id'); // Check for duplicates, only if this is an already existing item if (!empty($entity_id) && !is_null($entity_id)) { // Set data from the entity if the prefix is null if (is_null($prefix)) { $prefix = $this->getPrefix($entity); $url = $prefix . $slug; } // Set data from the entity if the slug is null if (is_null($slug)) { $slug = $entity->urlSlug(); $url = $prefix . $slug; } // Set it to the item's ID if empty if (is_null($slug)) { $slug = $entity_id . ""; $url = $prefix . $slug; } $slug_orig = $slug; $unique = $this->checkUnique($url, $entity_id, $url_id); $counter = 2; while (!$unique) { $slug = $slug_orig . '-' . $counter; $url = $prefix . $slug; $unique = $this->checkUnique($url, $entity_id, $url_id); $counter++; } // Add it to the list of saved URLs $this->savedUrls[$url] = $entity_id; } $url_item->set('item_id', $entity->get('id')); $url_item->set('prefix', $prefix); $url_item->set('slug', $slug); $url_item->set('url', $url); $url_item->set('type', $metadata->name); $entity->set($url_field, $url_item); $em->persist($url_item); // Skip this if the url hasn't changed if (!$new_url && $current_url == $url) { return; } $url_metadata = $em->getClassMetadata('CMF\\Model\\URL'); $url_changeset = $uow->getEntityChangeSet($url_item); if (!empty($url_changeset)) { $uow->recomputeSingleEntityChangeSet($url_metadata, $url_item); } else { $uow->computeChangeSet($url_metadata, $url_item); } $uow->recomputeSingleEntityChangeSet($metadata, $entity); $associations = $metadata->getAssociationMappings(); foreach ($associations as $association_name => $association) { // Only do it if it's the inverse side, to prevent the dreaded infinite recursion if (!$association['isOwningSide']) { $items = $entity->{$association_name}; if (!empty($items)) { foreach ($items as $item) { $this->process($item, $em, $uow); } } } } } }
/** * The URL-friendly identifier for the model. Uses the static slug_fields property to generate it. * @see CMF\Model\Base::$_slug_fields * @return string */ public function urlSlug() { $class_name = get_class($this); $self = $this; $values = array_map(function ($prop) use($self) { return $self->{$prop}; }, $class_name::$_slug_fields); return \CMF::slug(implode(' ', $values), true, true); }
/** @inheritdoc */ public static function displayForm($value, &$settings, $model) { if (!is_array($value)) { $value = array('src' => $value); } $metadata = $model->metadata(); $settings = static::settings($settings); $settings['label'] = isset($settings['label']) ? $settings['label'] : true; $settings['required'] = isset($settings['required']) ? $settings['required'] : false; $settings['errors'] = $model->getErrorsForField($settings['mapping']['fieldName']); $settings['has_errors'] = count($settings['errors']) > 0; $settings['model'] = $metadata->name; $preview_value = isset($value) && isset($value['src']) ? str_replace($settings['path'], '', $value['src']) : ''; // Prepare the crop settings if ($settings['crop'] === true) { $settings['crop'] = array('main' => array('title' => 'Main Crop')); } if (is_array($settings['crop'])) { $crop_options = array(); foreach ($settings['crop'] as $crop_id => $crop_settings) { if (is_string($crop_settings)) { $crop_settings = array('title' => $crop_settings); } $crop_settings['id'] = $crop_id; $crop_options[] = $crop_settings; } $settings['crop'] = $crop_options; } $content = strval(\View::forge('admin/fields/image.twig', array('settings' => $settings, 'value' => $value, 'preview_value' => $preview_value), false)); $attributes = array('class' => 'field-type-file image controls control-group' . ($settings['has_errors'] ? ' error' : ''), 'data-field-name' => $settings['mapping']['fieldName'], 'id' => 'field-' . \CMF::fieldId($settings['mapping']['fieldName'])); if (!(isset($settings['wrap']) && $settings['wrap'] === false)) { $content = html_tag('div', $attributes, $content); } $output = array('content' => $content, 'widget' => false); $output['js_data'] = $settings; return $output; }
/** * For the item links that Redactor produces */ public function itemLinks($value, $opts, $prefix = '', $suffix = '') { $default = array('field' => 'url', 'prefix' => $prefix, 'suffix' => $suffix); if (!is_array($opts)) { $default['field'] = $opts; $opts = array(); } elseif (isset($opts['field'])) { $default = $opts; $default['prefix'] = isset($default['prefix']) ? $default['prefix'] : ''; $default['suffix'] = isset($default['suffix']) ? $default['suffix'] : ''; } foreach ($opts as $opts_type => &$type_opts) { if (!is_array($type_opts)) { continue; } $type_opts['field'] = isset($type_opts['field']) ? $type_opts['field'] : $default['field']; $type_opts['prefix'] = isset($type_opts['prefix']) ? $type_opts['prefix'] : $default['prefix']; $type_opts['suffix'] = isset($type_opts['suffix']) ? $type_opts['suffix'] : $default['suffix']; } // Process the item links return \CMF::processItemLinks($value, function ($item, $type) use($opts, $default) { $item_opts = \Arr::get($opts, $type, $default); return $item_opts['prefix'] . $item->get($item_opts['field']) . $item_opts['suffix']; }); }