public static function preProcess($value, $settings, $model) { if (is_array($value)) { if (!empty($model)) { $model->changed = true; } if (isset($value['href']) && is_numeric($value['href'])) { $url = \CMF\Model\URL::find(intval($value['href'])); if (!empty($url)) { $value = new \CMF\Model\URL(); $value->populate(array('alias' => $url)); } } else { if (isset($value['external']) && intval($value['external'])) { $url = $model->get($settings['mapping']['fieldName']); if (empty($url)) { $url = new \CMF\Model\URL(); } $url->populate(array('url' => @$value['href'], 'slug' => '', 'prefix' => '', 'item_id' => null, 'type' => \CMF\Model\URL::TYPE_EXTERNAL, 'alias' => null)); return $url; } } } return $value; }
/** * 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; }
/** * 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); } } } } } }