Esempio n. 1
0
 public static function getValue($value, $settings, $model)
 {
     // Check if the src is set and the converted values are not - this means we need to check for
     // the progress file and possibly update the database
     if (is_array($value) && isset($value['src']) && strlen($value['src']) > 0 && (!isset($value['converted']) || empty($value['converted']))) {
         // See if the progress file exists
         $path = DOCROOT . $value['src'];
         if (file_exists($path . '.progress')) {
             $value['progress'] = json_decode(file_get_contents($path . '.progress'));
         } else {
             // It doesn't exist - populate the field
             if (isset($value['progress'])) {
                 unset($value['progress']);
             }
             $path_info = pathinfo($value['src']);
             $value['poster'] = $path_info['dirname'] . '/' . $path_info['basename'] . '.jpg';
             $value['converted'] = array('mp4' => $path_info['dirname'] . '/converted/' . $path_info['filename'] . '.mp4', 'webm' => $path_info['dirname'] . '/converted/' . $path_info['filename'] . '.webm');
             //$class = \CMF::getClass($model);
             $field_name = $settings['mapping']['fieldName'];
             $model->set($field_name, $value);
             \D::manager()->persist($model);
             \D::manager()->flush();
         }
     }
     return $value;
 }
Esempio n. 2
0
 public static function enableListener()
 {
     if (empty(static::$listener)) {
         return;
     }
     \D::manager()->getEventManager()->addEventSubscriber(static::$listener);
 }
Esempio n. 3
0
 /**
  * Purge all expired API keys from the database
  */
 public function removeOldKeys()
 {
     $keys = \CMF\Model\User\Apikey::select('item')->andWhere('item.expires_at < :now')->setParameter('now', new \DateTime())->getQuery()->getResult();
     foreach ($keys as $key) {
         \D::manager()->remove($key);
     }
     \D::manager()->flush();
 }
Esempio n. 4
0
 public function action_languageCanonicals()
 {
     $lang = \Config::get('language');
     $em = \D::manager();
     if (empty($lang)) {
         throw new \Exception("You do not have set any language for this site , this action is not available");
     }
     $canonicalLanguage = "";
     if (isset($_SERVER["HTTP_CONTENT_LANGUAGE"])) {
         $canonicalLanguage = $_SERVER["HTTP_CONTENT_LANGUAGE"];
         if ($canonicalLanguage == $lang) {
             throw new \Exception("Canonical Language id the same as Main site language");
         }
     } else {
         throw new \Exception("The Request has got not language set");
     }
     $jsonObject = null;
     try {
         $jsonObject = json_decode(file_get_contents('php://input'));
     } catch (\Exception $e) {
     }
     if (!empty($jsonObject) && !empty($jsonObject->data)) {
         foreach ($jsonObject->data as $table => $items) {
             foreach ($items as $canonical) {
                 $class = $canonical->class;
                 $item = $class::find($canonical->id);
                 if (!empty($item) && !empty($item->settings)) {
                     $settings = $item->settings;
                     if (!isset($settings['languages'])) {
                         $settings['languages'] = array();
                     }
                     if (isset($canonical->url)) {
                         if (!isset($settings['languages'][$canonicalLanguage])) {
                             $settings['languages'][$canonicalLanguage] = \Uri::base(false) . $item->url;
                         }
                         $settings['languages'][$canonicalLanguage] = $canonical->url;
                     } else {
                         if (isset($settings['languages'][$canonicalLanguage])) {
                             unset($settings['languages'][$canonicalLanguage]);
                         }
                     }
                     $item->set('settings', $settings);
                     $em->persist($item);
                 }
             }
         }
     }
     $em->flush();
     exit(true);
 }
Esempio n. 5
0
 public static function cleanOld()
 {
     $urls = \CMF\Model\URL::select('item')->getQuery()->getResult();
     $deleted = 0;
     foreach ($urls as $url) {
         $item = $url->item();
         if (empty($item)) {
             \D::manager()->remove($url);
             $deleted++;
         }
     }
     \D::manager()->flush();
     return $deleted;
 }
Esempio n. 6
0
 public function startQuery($sql, array $params = null, array $types = null)
 {
     if ($this->logger) {
         $this->logger->startQuery($sql, $params, $types);
     }
     // Store select queries for later use
     if (substr($sql, 0, 6) == 'SELECT') {
         if ($params) {
             // Attempt to replace placeholders so that we can log a final SQL query for profiler's EXPLAIN statement
             // (this is not perfect-- getPlaceholderPositions has some flaws-- but it should generally work with ORM-generated queries)
             $is_positional = is_numeric(key($params));
             list($sql, $params, $types) = \Doctrine\DBAL\SQLParserUtils::expandListParameters($sql, $params, $types);
             if (empty($types)) {
                 $types = array();
             }
             $placeholders = \Doctrine\DBAL\SQLParserUtils::getPlaceholderPositions($sql, $is_positional);
             if ($is_positional) {
                 $map = array_flip($placeholders);
             } else {
                 $map = array();
                 foreach ($placeholders as $name => $positions) {
                     foreach ($positions as $pos) {
                         $map[$pos] = $name;
                     }
                 }
             }
             ksort($map);
             $src_pos = 0;
             $final_sql = '';
             $first_param_index = key($params);
             foreach ($map as $pos => $replace_name) {
                 $final_sql .= substr($sql, $src_pos, $pos - $src_pos);
                 if ($sql[$pos] == ':') {
                     $src_pos = $pos + strlen($replace_name);
                     $index = trim($replace_name, ':');
                 } else {
                     $src_pos = $pos + 1;
                     $index = $replace_name + $first_param_index;
                 }
                 $final_sql .= \D::manager()->getConnection()->quote($params[$index], \Arr::get($types, $index));
             }
             $final_sql .= substr($sql, $src_pos);
             $this->queries[] = $final_sql;
         } else {
             $this->queries[] = $sql;
         }
     }
 }
Esempio n. 7
0
 /** inheritdoc */
 public static function instance()
 {
     $called_class = get_called_class();
     if (!isset($called_class::$instances[$called_class])) {
         $result = $called_class::select('item, start_page')->leftJoin('item.start_page', 'start_page')->setMaxResults(1)->getQuery()->getResult();
         if (count($result) == 0) {
             // Create the item if it doesn't exist
             $result = new $called_class();
             $result->blank();
             \D::manager()->persist($result);
             \D::manager()->flush();
             $called_class::$instances[$called_class] = $result;
         } else {
             $called_class::$instances[$called_class] = $result[0];
         }
     }
     return $called_class::$instances[$called_class];
 }
Esempio n. 8
0
 protected function pageTree($model = 'Model_Page_Base', $label = null, $active_url = null, $extra_fields = null)
 {
     $extra_fields_str = !is_null($extra_fields) ? ', page.' . implode(', page.', $extra_fields) : '';
     if ($model == 'Model_Page_Base') {
         $extra_fields_str = ', TYPE(page) AS type';
     }
     $nodes = $model::select('page.id, page.title, page.menu_title, page.lvl, page.lft, page.rgt' . $extra_fields_str . ', url.url, url.slug', 'page')->leftJoin('page.url', 'url')->where('page.lvl > 0')->andWhere('page.visible = true')->orderBy('page.root, page.lft', 'ASC')->getQuery();
     // Set the query hint if multi lingual!
     if (\CMF\Doctrine\Extensions\Translatable::enabled()) {
         $nodes->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker');
     }
     $nodes = $nodes->getArrayResult();
     $root_label = $label ? $label . '_level1' : 'level1';
     $crumbs_label = $label ? $label . '_crumbs' : 'crumbs';
     $uri = $active_url ? $active_url : \CMF::link(\CMF::original_uri());
     $nodes = \D::manager()->getRepository($model)->buildTree($nodes, array());
     $this->{$crumbs_label} = array();
     $this->processNodes($nodes, $uri, 1, $label, $model);
     $crumbs = $this->{$crumbs_label};
     ksort($crumbs);
     $this->{$crumbs_label} = $crumbs;
     return $this->{$root_label} = $nodes;
 }
Esempio n. 9
0
 /**
  * Deletes any imported local data that wasn't present in the import
  */
 protected static function processDeletions($model)
 {
     if (!isset(static::$_updatedEntities[$model]) || !is_array(static::$_updatedEntities[$model])) {
         return;
     }
     $metadata = $model::metadata();
     $polymorphic = $metadata->isInheritanceTypeJoined() || $metadata->isInheritanceTypeSingleTable();
     $class = $metadata->name;
     // Find all the ids of database items that have been imported
     $localIds = $class::getImportedIds();
     // Now get all the ids that have just been processed
     $processedClasses = array($metadata->name);
     $processedIds = array();
     if ($polymorphic && count($metadata->subClasses)) {
         foreach ($metadata->subClasses as $subClass) {
             if (!in_array($subClass, $processedClasses)) {
                 $processedClasses[] = $subClass;
             }
         }
     }
     foreach ($processedClasses as $processedClass) {
         if (!isset(static::$_updatedEntities[$processedClass]) || !is_array(static::$_updatedEntities[$processedClass])) {
             continue;
         }
         foreach (static::$_updatedEntities[$processedClass] as $id => $entity) {
             if (!in_array($entity->id, $processedIds)) {
                 $processedIds[] = $entity->id;
             }
         }
     }
     // Find the difference between the two
     asort($localIds);
     asort($processedIds);
     $diff = array_diff($localIds, $processedIds);
     // Delete ones that weren't imported this time
     if (count($diff)) {
         $entities = $class::select('item')->where('item.id IN(:ids)')->setParameter('ids', $diff)->getQuery()->getResult();
         foreach ($entities as $entity) {
             \D::manager()->remove($entity);
         }
     }
 }
Esempio n. 10
0
 /**
  * Adds default role to a new user if enabled in config
  *
  * @see \CMF\Model\User::_event_before_save()
  */
 private function _add_default_role()
 {
     // Make sure no roles exist already
     if (empty($this->roles) || !static::query()->related('roles')->get_one()) {
         // Check for default role
         if ($default_role = \Config::get('cmf.auth.default_role')) {
             $em = \D::manager();
             $query = $em->createQuery("SELECT r FROM CMF\\Model\\Role r WHERE r.name = '{$default_role}'");
             $record = $query->getSingleResult();
             if (!is_null($role)) {
                 $this->roles[] = $role;
             }
         }
     }
 }
Esempio n. 11
0
 public static function getOptionsStatic(&$settings, $model)
 {
     $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 = array();
     $tree_types = array();
     $types = $target_class::select('item.type')->distinct()->where('item.item_id IS NOT NULL')->orderBy('item.type', 'ASC')->getQuery()->getScalarResult();
     foreach ($types as $type) {
         $type = $type['type'];
         if (!class_exists($type)) {
             continue;
         }
         $metadata = $type::metadata();
         $root_class = $metadata->rootEntityName;
         if (isset($root_class)) {
             $type = $root_class;
         }
         $name = $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');
             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::buildTreeOptionsStatic($tree, $prop, array());
             continue;
         }
         $items = $type::select("item.id, item.{$prop}, url.url, url.id url_id")->leftJoin('item.url', 'url')->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) {
                 $group[strval($item[$prop])] = $item['url'];
             }
             $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;
 }
Esempio n. 12
0
 /**
  * Populates the 'tables > classes' and 'classes > tables' maps.
  * @return void
  */
 protected static function initClassTableMap()
 {
     $em = \D::manager();
     $driver = $em->getConfiguration()->getMetadataDriverImpl();
     static::$tables_to_classes = array();
     static::$classes_to_tables = array();
     static::$active_classes = array();
     // Populate translatable fields
     $translateListener = \CMF\Doctrine\Extensions\Translatable::getListener();
     // Loop through all Doctrine's class names, get metadata for each and populate the maps
     foreach ($driver->getAllClassNames() as $class_name) {
         $metadata = $em->getClassMetadata($class_name);
         if ($translateListener !== null) {
             $tConfig = $translateListener->getConfiguration($em, $class_name);
             if (is_array($tConfig) && isset($tConfig['fields']) && is_array($tConfig['fields'])) {
                 static::$translatable[$class_name] = $tConfig['fields'];
             }
         }
         if ($metadata->inheritanceType === ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_TABLE) {
             static::$tables_to_classes[$metadata->table['name']] = $metadata->rootEntityName;
         } else {
             static::$tables_to_classes[$metadata->table['name']] = $class_name;
         }
         static::$classes_to_tables[$class_name] = $metadata->table['name'];
         if (!$metadata->isMappedSuperclass && is_subclass_of($class_name, 'CMF\\Model\\Base') && $class_name::hasPermissions()) {
             if (count($metadata->parentClasses) > 0) {
                 $parent_class = $metadata->parentClasses[0];
                 if (!isset(static::$active_classes[$parent_class])) {
                     static::$active_classes[$parent_class] = array($parent_class, $class_name);
                 } else {
                     static::$active_classes[$parent_class][] = $class_name;
                 }
             } else {
                 if (!isset(static::$active_classes[$class_name])) {
                     static::$active_classes[$class_name] = array($class_name);
                 }
             }
         }
     }
 }
Esempio n. 13
0
 /**
  * Save everything in the entire DB again
  */
 public function action_save_all()
 {
     try {
         set_time_limit(0);
         ini_set('memory_limit', '512M');
     } catch (\Exception $e) {
         // Nothing!
     }
     // Get driver and get all class names
     $driver = \D::manager()->getConfiguration()->getMetadataDriverImpl();
     $this->classNames = $driver->getAllClassNames();
     foreach ($this->classNames as $class) {
         if (is_subclass_of($class, '\\CMF\\Model\\Base')) {
             $metadata = $class::metadata();
             // Don't process super classes!
             if ($class::superclass() || $metadata->isMappedSuperclass) {
                 continue;
             }
             $class::saveAll();
             \D::manager()->clear();
             sleep(1);
         }
     }
     \Session::set_flash('main_alert', array('attributes' => array('class' => 'alert-success'), 'msg' => \Lang::get('admin.messages.save_all_success')));
     \Response::redirect_back();
 }
Esempio n. 14
0
 protected function metadata1()
 {
     $metadata = \D::manager()->getClassMetadata('CMF\\Model\\Base');
 }
Esempio n. 15
0
 /**
  * For asyncronous saving - populates a model with the posted data and responds in JSON
  */
 public function action_populate($table_name, $id = null)
 {
     // Find class name and metadata etc
     $class_name = \Admin::getClassForTable($table_name);
     if ($class_name === false) {
         return $this->show404(null, "type");
     }
     if (!\CMF\Auth::can('edit', $class_name)) {
         return $this->show403('action_singular', array('action' => \Lang::get('admin.verbs.edit'), 'resource' => strtolower($class_name::singular())));
     }
     // Set the output content type
     $this->headers = array("Content-Type: text/plain");
     // If $id is null, we're populating multiple items
     if ($id === null) {
         // Construct the output
         $result = array('success' => true, 'num_updated' => 0);
         $post_data = \Input::post();
         $ids = array_keys($post_data);
         $em = \D::manager();
         if (count($ids) == 0) {
             return \Response::forge(json_encode($result), $this->status, $this->headers);
         }
         // Get the items we need to save
         $items = $class_name::select('item')->where('item.id IN(?1)')->setParameter(1, $ids)->getQuery()->getResult();
         if (count($items) == 0) {
             return \Response::forge(json_encode($result), $this->status, $this->headers);
         }
         foreach ($items as $item) {
             $id = $item->id;
             if (!isset($post_data[$id])) {
                 continue;
             }
             $result['num_updated'] += 1;
             $data = $post_data[$id];
             $item->populate($data, false);
             if (!$item->validate()) {
                 $result['success'] = false;
             }
             $em->persist($item);
         }
         // Try and save them all
         try {
             $em->flush();
         } catch (\Exception $e) {
             $result['success'] = false;
             $result['error'] = $e->getMessage();
         }
         // Return the JSON response
         return \Response::forge(json_encode($result), $this->status, $this->headers);
     }
     // Find the model, return 404 if not found
     $model = $class_name::find($id);
     if (is_null($model)) {
         return $this->show404(null, "item");
     }
     // Populate with the POST data
     $model->populate(\Input::post(), false);
     // Construct the output
     $result = array('success' => false);
     // Check validation
     if ($model->validate()) {
         $result['success'] = true;
     } else {
         $result['validation_errors'] = $model->errors;
     }
     // Try and save it
     try {
         $em = \D::manager();
         $em->persist($model);
         $em->flush();
         $result['updated_at'] = $model->updated_at->format("d/m/Y \\a\\t H:i:s");
     } catch (\Exception $e) {
         $result['success'] = false;
         $result['error'] = $e->getMessage();
     }
     // Return the JSON response
     return \Response::forge(json_encode($result), $this->status, $this->headers);
 }
Esempio n. 16
0
 /**
  * Performs hydrations for the class specified
  */
 protected function performHydrations($class, $ids = null)
 {
     if (!isset($this->hydrations[$class])) {
         return;
     }
     $extra = '';
     if (is_array($ids)) {
         if (!($class == $this->class && count($ids) == $this->meta['total'])) {
             $extra = " WHERE item.id IN(" . implode(',', $ids) . ")";
         }
     }
     foreach ($this->hydrations[$class] as $assoc) {
         \D::manager()->createQuery("SELECT item, {$assoc} FROM {$class} item LEFT JOIN item.{$assoc} {$assoc}" . $extra)->getResult();
     }
 }
Esempio n. 17
0
 /** inheritdoc */
 public static function instance()
 {
     $called_class = get_called_class();
     if (!isset($called_class::$instances[$called_class])) {
         $result = $called_class::select('item')->setMaxResults(1)->getQuery()->getResult();
         if (count($result) == 0) {
             $root_node = $called_class::getRootNode(true);
             // Create the item if it doesn't exist
             $result = new $called_class();
             $result->blank();
             $called_class::repository()->persistAsFirstChildOf($result, $root_node);
             \D::manager()->flush();
             $called_class::$instances[$called_class] = $result;
         } else {
             $called_class::$instances[$called_class] = $result[0];
         }
     }
     return $called_class::$instances[$called_class];
 }
Esempio n. 18
0
 /**
  * Converts any old image fields (strings) into the new style object ones
  */
 public function convertimages()
 {
     $em = \D::manager();
     $driver = $em->getConfiguration()->getMetadataDriverImpl();
     $tables_fields = array();
     $sql = array();
     // Loop through all the model metadata and check for image fields
     foreach ($driver->getAllClassNames() as $class) {
         $metadata = $em->getClassMetadata($class);
         $fields = $metadata->fieldMappings;
         $convert = array();
         foreach ($fields as $field_name => $field) {
             if ($field['type'] == 'image') {
                 $convert[] = $field_name;
             }
         }
         if (count($convert) > 0) {
             $table = $metadata->table['name'];
             $refl_fields = $metadata->reflFields;
             foreach ($convert as $convert_field) {
                 if (isset($refl_fields[$convert_field]) && $refl_fields[$convert_field]->class != $class) {
                     $field_table = \Admin::getTableForClass($refl_fields[$convert_field]->class);
                 } else {
                     $field_table = $table;
                 }
                 $table_fields = \Arr::get($tables_fields, $field_table, array());
                 if (!in_array($convert_field, $table_fields)) {
                     $table_fields[] = $convert_field;
                 }
                 $tables_fields[$field_table] = $table_fields;
             }
         }
     }
     foreach ($tables_fields as $table => $fields) {
         $results = \DB::query("SELECT id, " . implode(', ', $fields) . " FROM {$table}")->execute();
         foreach ($results as $result) {
             foreach ($fields as $field) {
                 $image = @unserialize($result[$field]);
                 if ($image === false) {
                     $newimage = array('src' => $result[$field], 'alt' => '');
                     $newimage = \DB::quote(serialize($newimage));
                     $sql[] = "UPDATE {$table} SET {$field} = {$newimage} WHERE id = " . $result['id'];
                 }
             }
         }
     }
     foreach ($sql as $query) {
         \DB::query($query)->execute();
     }
     \Cli::write('Done!', 'green');
 }
Esempio n. 19
0
 /**
  * Sync files to the DB table
  */
 public static function syncFileFields()
 {
     if (!\Config::get('cmf.cdn.enabled')) {
         return;
     }
     try {
         set_time_limit(0);
         ini_set('memory_limit', '512M');
     } catch (\Exception $e) {
         // Nothing!
     }
     $em = \D::manager();
     $driver = $em->getConfiguration()->getMetadataDriverImpl();
     $tables_fields = array();
     $sql = array();
     $localAdaper = static::adapter();
     $cdn = static::getCDNAdapter();
     $useCdn = \Config::get('cmf.cdn.sync.enabled') && !empty($cdn);
     $staticFiles = array();
     // Loop through all the model metadata and check for image fields
     foreach ($driver->getAllClassNames() as $class) {
         $metadata = $em->getClassMetadata($class);
         $fields = $metadata->fieldMappings;
         $file_fields = array();
         foreach ($fields as $field_name => $field) {
             if ($field['type'] == 'image' || $field['type'] == 'file') {
                 $file_fields[$field_name] = $field['type'];
             }
         }
         if (count($file_fields) === 0) {
             continue;
         }
         $items = $class::select('item')->getQuery()->getResult();
         foreach ($items as $num => $item) {
             foreach ($file_fields as $field_name => $field_type) {
                 $field_value = $item->{$field_name};
                 if (is_array($field_value) && !empty($field_value['src'])) {
                     $path = static::getDocumentRoot() . $field_value['src'];
                     if (file_exists($path)) {
                         $files = \DB::query("SELECT * FROM `_files` WHERE `path` = :path AND `storage` = 'local' ORDER BY `id` DESC LIMIT 1")->bind('path', $field_value['src'])->execute()->as_array();
                         if (!count($files)) {
                             // Update file entry to the database
                             \DB::insert('_files')->set(array('path' => $field_value['src'], 'url' => '/' . $field_value['src'], 'storage' => 'local', 'type' => $metadata->name, 'field' => $field_name, 'created_at' => date('Y-m-d H:i:s', filectime($path)), 'updated_at' => date('Y-m-d H:i:s', filemtime($path))))->execute();
                         }
                         if ($useCdn && $field_type == 'file') {
                             $cachedFiles = \DB::query("SELECT * FROM `_files` WHERE `path` = :path AND `storage` = 'cdn' ORDER BY `id` DESC LIMIT 1")->bind('path', $field_value['src'])->execute();
                             if (!count($cachedFiles)) {
                                 // Update cached file entry to the database
                                 $cachedResult = \DB::insert('_files')->set(array('path' => $field_value['src'], 'url' => '/' . $field_value['src'], 'storage' => 'cdn', 'type' => $metadata->name, 'field' => $field_name, 'created_at' => date('Y-m-d H:i:s', filectime($path)), 'updated_at' => date('Y-m-d H:i:s', filemtime($path))))->execute();
                                 $cachedFileId = intval(@$cachedResult[0]);
                             } else {
                                 $cachedFileId = intval($cachedFiles->get('id'));
                             }
                             if (!empty($cachedFileId)) {
                                 // Just upload files straight to the CDN
                                 $staticFiles[] = $field_value['src'];
                             }
                         }
                     }
                 }
             }
         }
     }
     if ($useCdn) {
         foreach ($staticFiles as $staticFile) {
             try {
                 // Write the file to CDN if it doesn't exist there
                 if (!$cdn->has($staticFile)) {
                     if (\Fuel::$is_cli) {
                         \Cli::write("uploading '{$staticFile}' to CDN");
                     }
                     $cdn->write($staticFile, $localAdaper->read($staticFile), array('visibility' => 'public'));
                 }
             } catch (\Exception $e) {
             }
         }
     }
 }
Esempio n. 20
0
 /**
  * Create a new entity and inject request params into it
  * @return array
  */
 public function action_add()
 {
     $model = $this->model;
     $data = \Arr::get(\Input::json(), 'data', array());
     $entity = null;
     if (isset($data['id']) && $data['id']) {
         $entity = $model::find($data['id']);
     }
     if (!$entity) {
         $entity = new $model();
     }
     $entity->populate($data);
     $success = true;
     $msg = '';
     try {
         \D::manager()->persist($entity);
         \D::manager()->flush();
     } catch (\Exception $e) {
         $success = false;
         $msg = $e->getMessage();
     }
     if ($success) {
         $this->http_status = 201;
         $this->params['id'] = $this->id = $entity->id;
         $this->unique = true;
         $this->response->set_header('Location', \Uri::base(false) . 'api/' . $this->singular . '/' . $entity->id);
         $result = $this->getQuery()->getResult();
         if (!count($result)) {
             throw new \HttpException(ucfirst($this->singular) . ' was not found', \HttpException::NOT_FOUND);
         }
         return $result;
     }
     return array('error' => $msg);
 }
 /**
  * @param object     $entity
  * @param Constraint $constraint
  *
  * @throws UnexpectedTypeException
  * @throws ConstraintDefinitionException
  */
 public function validate($entity, Constraint $constraint)
 {
     if (!is_array($constraint->fields) && !is_string($constraint->fields)) {
         throw new UnexpectedTypeException($constraint->fields, 'array');
     }
     if (null !== $constraint->errorPath && !is_string($constraint->errorPath)) {
         throw new UnexpectedTypeException($constraint->errorPath, 'string or null');
     }
     $fields = (array) $constraint->fields;
     if (0 === count($fields)) {
         throw new ConstraintDefinitionException('At least one field has to be specified.');
     }
     if ($constraint->em) {
         $em = \D::manager($constraint->em);
     } else {
         $em = \D::manager();
     }
     $className = $this->context->getClassName();
     $class = $em->getClassMetadata($className);
     /* @var $class \Doctrine\Common\Persistence\Mapping\ClassMetadata */
     $criteria = array();
     foreach ($fields as $fieldName) {
         if (!$class->hasField($fieldName) && !$class->hasAssociation($fieldName)) {
             throw new ConstraintDefinitionException(sprintf("The field '%s' is not mapped by Doctrine, so it cannot be validated for uniqueness.", $fieldName));
         }
         $criteria[$fieldName] = $class->reflFields[$fieldName]->getValue($entity);
         if ($constraint->ignoreNull && null === $criteria[$fieldName]) {
             return;
         }
         if ($class->hasAssociation($fieldName)) {
             /* Ensure the Proxy is initialized before using reflection to
              * read its identifiers. This is necessary because the wrapped
              * getter methods in the Proxy are being bypassed.
              */
             $em->initializeObject($criteria[$fieldName]);
             $relatedClass = $em->getClassMetadata($class->getAssociationTargetClass($fieldName));
             $relatedId = $relatedClass->getIdentifierValues($criteria[$fieldName]);
             if (count($relatedId) > 1) {
                 throw new ConstraintDefinitionException("Associated entities are not allowed to have more than one identifier field to be " . "part of a unique constraint in: " . $class->getName() . "#" . $fieldName);
             }
             $criteria[$fieldName] = array_pop($relatedId);
         }
     }
     $repository = $em->getRepository($className);
     $result = $repository->{$constraint->repositoryMethod}($criteria);
     /* If the result is a MongoCursor, it must be advanced to the first
      * element. Rewinding should have no ill effect if $result is another
      * iterator implementation.
      */
     if ($result instanceof \Iterator) {
         $result->rewind();
     } elseif (is_array($result)) {
         reset($result);
     }
     /* If no entity matched the query criteria or a single entity matched,
      * which is the same as the entity being validated, the criteria is
      * unique.
      */
     if (0 === count($result) || 1 === count($result) && $entity === ($result instanceof \Iterator ? $result->current() : current($result))) {
         return;
     }
     $errorPath = null !== $constraint->errorPath ? $constraint->errorPath : $fields[0];
     $this->context->addViolationAt($errorPath, $constraint->message, array(), $criteria[$fields[0]]);
 }
Esempio n. 22
0
 public function shutdown()
 {
     $queries = $this->logger->queries;
     $controller = $this->request->controller_instance;
     $tables = array();
     $subqueries = array();
     $queryTables = array();
     $sql = '';
     // Add the template files to be checked
     $template_loader = \View_Twig::loader();
     if (!is_null($template_loader) && method_exists($template_loader, 'getFiles')) {
         $templates = $template_loader->getFiles();
         $this->files = array_unique(array_merge($this->files, $templates));
     }
     // Add all loaded files within the app root, excluding cache and model proxies
     $this->files = array_merge($this->files, array_filter(get_included_files(), function ($path) {
         return strpos($path, APPPATH) === 0 && strpos($path, APPPATH . 'cache') !== 0 && strpos($path, APPPATH . 'classes/proxy') !== 0;
     }));
     $model_classes = array_filter(get_declared_classes(), function ($class) {
         return strpos($class, 'Model_') !== false;
     });
     // Construct an allowed list of tables for the cache queries
     $em = \D::manager();
     foreach ($model_classes as $model) {
         $meta = $em->getClassMetadata($model);
         if ($meta->isMappedSuperclass || !isset($meta->columnNames['updated_at']) || $meta->rootEntityName != $meta->name) {
             continue;
         }
         if (!in_array($meta->table['name'], $tables)) {
             $tables[] = $meta->table['name'];
         }
     }
     // Remove the app path from each file path, making them relative
     $this->files = array_map(function ($path) {
         return str_replace(PROJECTROOT, '', $path);
     }, $this->files);
     // Construct ourselves a number of sub queries to check all the relevant records in the database
     $num = 0;
     foreach ($queries as $query) {
         $parser = new \PHPSQL\Parser();
         $parsed = $parser->parse($query, true);
         if (!isset($parsed['FROM']) || count($parsed['FROM']) === 0) {
             continue;
         }
         $aliases = array();
         foreach ($parsed['FROM'] as $part) {
             if ($part['expr_type'] == 'table' && in_array($part['table'], $tables)) {
                 $aliases[] = isset($part['alias']['name']) ? $part['alias']['name'] : $part['table'];
             }
         }
         $from_pos = $parsed['FROM'][0]['position'];
         if (isset($parsed['ORDER']) && count($parsed['ORDER']) > 0) {
             $append = ' FROM ' . substr($query, $from_pos, $parsed['ORDER'][0]['position'] - $from_pos - 10);
         } else {
             $append = ' FROM ' . substr($query, $from_pos);
         }
         if (count($aliases) > 1) {
             $append = ', (COUNT(' . implode('.id)+COUNT(', $aliases) . '.id)) as count' . $append;
         } else {
             if (count($aliases) === 1) {
                 $append = ', COUNT(' . $aliases[0] . '.id) as count' . $append;
             } else {
                 continue;
             }
         }
         $subqueries[] = 'q' . $num;
         $queryTables[] = '(SELECT ' . (count($aliases) > 1 ? 'GREATEST(' : '') . 'COALESCE(MAX(' . implode('.updated_at),\'1000-01-01\'), COALESCE(MAX(', $aliases) . '.updated_at),\'1000-01-01\')' . (count($aliases) > 1 ? ')' : '') . ' AS updated_at' . $append . ') q' . $num;
         $num++;
     }
     if (count($this->queries) > 0) {
         foreach ($this->queries as $query) {
             $parser = new \PHPSQL\Parser();
             $parsed = $parser->parse($query, true);
             $field = null;
             if (!isset($parsed['FROM']) || count($parsed['FROM']) === 0) {
                 continue;
             }
             if (!isset($parsed['SELECT']) || count($parsed['SELECT']) === 0) {
                 continue;
             }
             foreach ($parsed['SELECT'] as $select) {
                 if ($select['expr_type'] == 'colref') {
                     $field = $select['base_expr'];
                     break;
                 }
             }
             if ($field === null) {
                 continue;
             }
             $aliases = array();
             foreach ($parsed['FROM'] as $part) {
                 if ($part['expr_type'] == 'table') {
                     $aliases[] = isset($part['alias']['name']) ? $part['alias']['name'] : $part['table'];
                 }
             }
             $from_pos = $parsed['FROM'][0]['position'];
             if (isset($parsed['ORDER']) && count($parsed['ORDER']) > 0) {
                 $append = ' FROM ' . substr($query, $from_pos, $parsed['ORDER'][0]['position'] - $from_pos - 10);
             } else {
                 $append = ' FROM ' . substr($query, $from_pos);
             }
             if (count($aliases) > 1) {
                 $append = ', (COUNT(' . implode('.' . $field . ')+COUNT(', $aliases) . '.' . $field . ')) as count' . $append;
             } else {
                 if (count($aliases) === 1) {
                     $append = ', COUNT(' . $aliases[0] . '.' . $field . ') as count' . $append;
                 } else {
                     continue;
                 }
             }
             $subqueries[] = 'q' . $num;
             $queryTables[] = '(SELECT ' . (count($aliases) > 1 ? 'GREATEST(' : '') . 'COALESCE(MAX(' . implode('.' . $field . '),\'1000-01-01\'), COALESCE(MAX(', $aliases) . '.' . $field . '),\'1000-01-01\')' . (count($aliases) > 1 ? ')' : '') . ' AS updated_at' . $append . ') q' . $num;
             $num++;
         }
     }
     if (count($queryTables)) {
         // TODO: proper chunking of subqueries! For now, we will truncate them if they exeed MySQL's limit of 61
         if (count($queryTables) > 60) {
             $queryTables = array_slice($queryTables, 0, 60);
             $subqueries = array_slice($subqueries, 0, 60);
         }
         // Complete the mega query that will check if items are updated or not...
         if (count($subqueries) > 1) {
             $sql = 'SELECT GREATEST(' . implode('.updated_at, ', $subqueries) . '.updated_at) AS updated_at, (' . implode('.count+', $subqueries) . '.count) AS count FROM ' . implode(', ', $queryTables);
         } else {
             $sql = 'SELECT q0.updated_at, q0.count FROM ' . implode(', ', $queryTables);
         }
         // Run the query - this must be done now because we can't reliably get the correct results from what we have
         try {
             $result = \DB::query($sql)->execute()->as_array();
             $result = $result[0];
             $result['updated_at'] = strtotime($result['updated_at']);
         } catch (\Exception $e) {
             // We can't continue if the query doesn't work
             return;
         }
     }
     // Add the rest of the stuff to the result
     $result['query_count'] = $num;
     $result['sql'] = $sql;
     $result['files'] = $this->files;
     $result['content'] = strval($this->request->response);
     $result['nocache'] = \CMF\Cache::getNoCacheAreas($result['content']);
     $result['logs_made'] = \CMF\Log::$logs_made;
     $result['content-type'] = 'text/html; charset=utf-8';
     $result['template'] = \CMF::$template;
     $result['module'] = \CMF::$module;
     // Store the content type header if it's set
     $headers = headers_list();
     foreach ($headers as $header) {
         if (stripos($header, 'content-type: ') === 0) {
             $result['content-type'] = substr($header, 14);
             break;
         }
     }
     // serialize and write it to disk
     \CMF\Cache::writeCacheFile($this->path, serialize($result));
 }
Esempio n. 23
0
 /**
  * Ensures that there is at least an 'all' permission set for every resource
  * @return void
  */
 public static function create_permissions()
 {
     $actions = static::all_actions();
     $actions[] = 'all';
     $activeClasses = \CMF\Admin::activeClasses();
     $activeClasses['user_defined'] = array_keys(\Config::get('cmf.auth.resources', array()));
     $roles = Role::select('item')->getQuery()->getResult();
     $em = \D::manager();
     foreach ($activeClasses as $parent_class => $classes) {
         foreach ($classes as $class_name) {
             $count = intval(Permission::select("count(item)")->where("item.resource = '{$class_name}'")->andWhere("item.action = 'all'")->getQuery()->getSingleScalarResult());
             if ($count == 0) {
                 $permission = new Permission();
                 $permission->set('action', 'all');
                 $permission->set('resource', $class_name);
                 $em->persist($permission);
                 foreach ($roles as $role) {
                     $role->add('permissions', $permission);
                     $em->persist($role);
                 }
             }
         }
     }
     $em->flush();
 }
 /**
  * Get the auto translatable fields which have changed for an entity
  */
 protected function getChangeset($entity)
 {
     $entity_class = $entity->metadata()->name;
     $translatableFields = \CMF\Admin::getTranslatable($entity_class);
     $excludedFields = $entity_class::excludeAutoTranslations();
     if (\Input::param('force_translate', false) !== false) {
         return array_values(array_diff(array_values($translatableFields), $excludedFields));
     } else {
         $changeset = \D::manager()->getUnitOfWork()->getEntityChangeSet($entity);
         if (is_array($changeset)) {
             $changeset = array_keys($changeset);
         } else {
             $changeset = array();
         }
     }
     return array_diff(array_values(array_intersect($translatableFields, $changeset)), $excludedFields);
 }
Esempio n. 25
0
 /**
  * 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;
 }
Esempio n. 26
0
 /**
  * Creates a super user
  * @return array
  */
 public static function createSuperUser($email = '*****@*****.**', $username = '******', $password = null)
 {
     // Load up the admin module and it's classes, otherwise we won't get
     // access to the admin user class
     \Module::load('admin');
     if (\Fuel::$is_cli) {
         $email = \Cli::prompt('Enter an email address', $email);
         $username = \Cli::prompt('Enter a user name', $username);
         $first = true;
         while ($first || strlen($password) > 0 && strlen($password) < 6) {
             $password = \Cli::prompt('Enter a password (leave blank to generate one)');
             if (strlen($password) > 0 && strlen($password) < 6) {
                 \Cli::error('The password must be 6 characters or more!');
             }
             $first = false;
         }
         $confirm_password = '';
         if (empty($password)) {
             // The user left the password field blank, so we are generating one
             $gen = new PWGen(3, false, false, false, false, false, false);
             $password = $confirm_password = $gen->generate() . '-' . $gen->generate() . '-' . $gen->generate();
         } else {
             // If the user entered a password, we need them to confirm it
             while ($confirm_password != $password) {
                 $confirm_password = \Cli::prompt('Confirm password');
                 if ($confirm_password != $password) {
                     \Cli::error('The passwords do not match!');
                 }
             }
         }
     }
     // Check if the user exists
     $em = \D::manager();
     $user = \Admin\Model_User::select('item')->where("item.username = '******'")->getQuery()->getResult();
     $exists = count($user) > 0;
     if ($exists) {
         $user = $user[0];
     } else {
         $user = new \Admin\Model_User();
     }
     // Populate the user
     $user->set('email', $email);
     $user->set('username', $username);
     $user->set('password', $password);
     $user->set('confirm_password', $confirm_password);
     $user->set('super_user', true);
     // Create the admin role
     $role = \CMF\Model\Role::findBy(array("name = 'admin'"))->getQuery()->getResult();
     if (count($role) == 0) {
         $role = new \CMF\Model\Role();
         $role->set('name', 'admin');
         $role->set('description', 'users of this admin site');
         $em->persist($role);
     } else {
         $role = $role[0];
     }
     $user->add('roles', $role);
     // Validate the newly created user
     if (!$user->validate()) {
         if (\Fuel::$is_cli) {
             \Cli::write('There was something wrong with the info you entered. Try again!', 'red');
             static::createSuperUser();
         } else {
             return array('errors' => $user->errors);
         }
     }
     $em->persist($user);
     $em->flush();
     \Cli::write($exists ? "\n\tExisting super user updated:" : "\n\tNew super user created:", 'light_gray');
     \Cli::write("\tusername:    "******"\n\tpassword:    "******"\n", 'light_cyan');
 }
Esempio n. 27
0
 /**
  * Adds a URL that will redirect to another by ID
  */
 public static function addRedirectUrl($url, $parentId, $type = 301, $limit = 2)
 {
     if (empty($url)) {
         return;
     }
     if (empty($parentId)) {
         return;
     }
     // Don't bother if the parent doesn't exist
     $parentCount = intval(\CMF\Model\URL::select("count(item.id)")->where('item.id = :parentid')->setParameter('parentid', intval($parentId))->getQuery()->getSingleScalarResult());
     if ($parentCount === 0) {
         return;
     }
     // Standardise the passed URL
     $url = trim($url, '/');
     if (stripos($url, 'http') === 0 && ($urlInfo = parse_url($url))) {
         $url = trim($url['path'], '/');
     }
     $parts = explode('/', $url);
     if (empty($parts)) {
         return;
     }
     // Get existing redirects
     $existing = \CMF\Model\URL::select('item')->where('item.parent_id = :parentid')->setParameter('parentid', intval($parentId))->orderBy('item.updated_at', 'ASC')->getQuery()->getResult();
     // Check for redirects with the same URL
     foreach ($existing as $existingUrl) {
         if ($existingUrl->url == '/' . $url) {
             $existingUrl->set('updated_at', new \DateTime());
             $existingUrl->set('type', strval($type));
             \D::manager()->persist($existingUrl);
             \D::manager()->flush($existingUrl);
             return $existingUrl;
         }
     }
     // Create the url unless the limit has been reached
     if (count($existing) >= $limit) {
         $redirect = $existing[0];
     } else {
         $redirect = new \CMF\Model\URL();
     }
     // Populate, save and return the new url object
     $redirect->populate(array('parent_id' => intval($parentId), 'item_id' => null, 'url' => '/' . $url, 'slug' => array_pop($parts), 'prefix' => '/' . implode('/', $parts) . (count($parts) ? '/' : ''), 'type' => strval($type)));
     \D::manager()->persist($redirect);
     \D::manager()->flush($redirect);
     return $redirect;
 }
Esempio n. 28
0
 /**
  * Gets called from action_index() when a model is found to extend CMF\Model|Node
  * @param  string $class_name
  * @return void
  */
 public function treeView($class_name)
 {
     \Admin::setCurrentClass($class_name);
     $metadata = $class_name::metadata();
     // Create static items
     \Admin::createStaticInstances($metadata);
     // Add some context for the template
     $this->plural = $class_name::plural();
     $this->singular = $class_name::singular();
     $this->icon = $class_name::icon();
     // 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');
     $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(), 'allowed_children' => $class_name::allowedChildren(), 'allowed_parents' => $class_name::allowedParents());
     foreach ($metadata->subClasses as $sub_class) {
         $subclass_metadata = $sub_class::metadata();
         $classes[$sub_class] = array('static' => $sub_class::_static(), 'superlock' => $sub_class::superlock(), 'plural' => $sub_class::plural(), 'singular' => $sub_class::singular(), 'icon' => $sub_class::icon(), 'table_name' => $subclass_metadata->table['name'], 'can_create' => \CMF\Auth::can('create', $sub_class), 'can_edit' => \CMF\Auth::can('edit', $sub_class), 'can_delete' => \CMF\Auth::can('delete', $sub_class), 'superclass' => false, 'allowed_children' => $sub_class::allowedChildren(), 'allowed_parents' => $sub_class::allowedParents(), 'disallowed_children' => $sub_class::disallowedChildren(), 'disallowed_parents' => $sub_class::disallowedParents());
     }
     // Item-specific permissions
     $user = \CMF\Auth::current_user();
     $item_permissions = array();
     $ids = array();
     $excluded_ids = array();
     $root_node = $class_name::getRootNode(true);
     $repo = \D::manager()->getRepository($class_name);
     $qb = $repo->getNodesHierarchyQueryBuilder($root_node);
     $this->tree_errors = null;
     $this->tree_is_valid = true;
     // If we have URLs, join them to the query
     if ($class_name::hasUrlField()) {
         $qb->addSelect('url, alias')->leftJoin('node.url', 'url')->leftJoin('url.alias', 'alias');
     }
     $q = $qb->getQuery();
     // Set the query hint if multi lingual!
     if (\CMF\Doctrine\Extensions\Translatable::enabled()) {
         $q->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker');
     }
     //$tree = $this->processTreeNodes(\D::manager()->getRepository($class_name)->childrenHierarchy($root_node), $metadata, $ids);
     $tree = $this->processTreeNodes($repo->buildTree($q->getArrayResult()), $metadata, $ids);
     if (!$user->super_user) {
         $permissions = \CMF\Model\Permission::select('item.id, item.action, item.resource, item.item_id')->leftJoin('item.roles', 'roles')->where("item.resource = '{$class_name}'")->andWhere("item.item_id IN(?1)")->andWhere("roles IN (?2)")->setParameter(1, $ids)->setParameter(2, $user->roles->toArray())->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;
             }
         }
         $tree = $this->filterTreeNodes($tree, $excluded_ids);
     } else {
         $this->tree_errors = $repo->verify();
         $this->tree_is_valid = $this->tree_errors === true;
     }
     // Import actions
     $importMethods = $class_name::importMethods();
     // Add more context for the template
     $this->table_name = $metadata->table['name'];
     $this->template = 'admin/item/tree.twig';
     $this->superlock = $class_name::superlock();
     $this->num_nodes = count($tree);
     // 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['tree'] = $tree;
     $this->js['item_permissions'] = $item_permissions;
     $this->js['excluded_ids'] = $excluded_ids;
     $this->js['classes'] = $classes;
     $this->js['table_name'] = $metadata->table['name'];
     $this->js['plural'] = $this->plural;
     $this->js['singular'] = $this->singular;
     $this->js['class_name'] = $class_name;
     // Permissions for JS
     $this->js['can_create'] = $can_create && $can_edit;
     $this->js['can_edit'] = $can_edit;
     $this->js['can_delete'] = $can_delete;
     $this->js['can_manage'] = $can_manage;
 }