/** * This function resolves any GUID into a fully qualified URL which can be relocated * to. It operates in multiple phases: * * 1. Check, whether the GUID is already known by NAP. In case we have the corresponding * node/leaf loaded, use its linking information directly. * 2. Look if we have a topic, in that case, we get the corresponding NAP node and use * it to resolve the permalink. If that object is not retrievable, the lookup * fails. * 3. We check whether the object in question has a topic as one of its ancestors. If yes, * that topic and its corresponding component is used to lookup the GUID, which might * fail. * 4. As a last resort we have to iterate over all NAP topics to do the resolving. * * @param string $guid The GUID to resolve. * @return string The full HTTP relocation'able URL to the GUID. */ function resolve_permalink($guid) { // resolves a guid into a fully qualified url, uses some heuristics for that, mainly replaces // the nap permalink resolver, with the difference that it will be based on the // components permalink interface code. $nav = new midcom_helper_nav(); // Step 1: Maybe NAP already knows the topic. $napobj = $nav->resolve_guid($guid); if ($napobj) { return $napobj[MIDCOM_NAV_FULLURL]; } try { $object = midcom::get('dbfactory')->get_object_by_guid($guid); } catch (midcom_error $e) { debug_add("Failed to resolve the GUID {$guid}, this is most probably an access denied error.", MIDCOM_LOG_ERROR); debug_add('Last MidCOM error string: ' . $e->getMessage()); return null; } $metadata = midcom_helper_metadata::retrieve($object); if (!$metadata->is_object_visible_onsite()) { return null; } if (is_a($object, 'midcom_db_topic')) { $napobj = $nav->get_node($object->id); if (!$napobj) { debug_add("Failed to retrieve the NAP object for topic {$object->id}.", MIDCOM_LOG_INFO); return null; } return $napobj[MIDCOM_NAV_FULLURL]; } if (is_a($object, 'midcom_db_attachment')) { // Faster linking to attachments $parent = $object->get_parent(); if (is_a($parent, 'midcom_db_topic') && $nav->is_node_in_tree($parent->id, $nav->get_root_node())) { $napobj = $nav->get_node($parent->id); return $napobj[MIDCOM_NAV_FULLURL] . $object->name; } else { return "{$GLOBALS['midcom_config']['midcom_site_url']}midcom-serveattachmentguid-{$object->guid}/{$object->name}"; } } // Ok, unfortunately, this is not an immediate topic. We try to traverse // upwards in the object chain to find a topic. $topic = null; $parent = $object->get_parent(); while ($parent) { if (is_a($parent, 'midcom_db_topic')) { // Verify that this topic is within the current sites tree, if it is not, // we ignore it. This might happen on symlink topics with static & co // which point to the outside f.x. if ($nav->is_node_in_tree($parent->id, $nav->get_root_node())) { $topic = $parent; break; } } $parent = $parent->get_parent(); } if ($topic !== null) { $return_value = $this->_resolve_permalink_in_topic($topic, $guid); if ($return_value != null) { return $return_value; } } // Bad, this means a full scan, // We need to try every topic for the GUID. $topic_qb = midcom_db_topic::new_query_builder(); $topic_qb->add_constraint('name', '<>', ''); $topic_qb->add_constraint('up', 'INTREE', midcom_core_context::get()->get_key(MIDCOM_CONTEXT_ROOTTOPIC)->id); $topics = $topic_qb->execute(); foreach ($topics as $topic) { $result = $this->_resolve_permalink_in_topic($topic, $guid); if ($result !== null) { return $result; } } // We were unable to find the GUID return null; }