/** * Tries to determine the topic GUID and component using NAPs reverse-lookup capabilities. * * If this fails, you have to set the members $topic_guid, $topic_url and * $component manually. */ function _process_topic() { $nav = new midcom_helper_nav(); $object = $nav->resolve_guid($this->source); if (!$object) { debug_add("Failed to resolve the topic, skipping autodetection."); return; } if ($object[MIDCOM_NAV_TYPE] == 'leaf') { $object = $nav->get_node($object[MIDCOM_NAV_NODEID]); } $this->topic_guid = $object[MIDCOM_NAV_GUID]; $this->topic_url = $object[MIDCOM_NAV_FULLURL]; $this->component = $object[MIDCOM_NAV_COMPONENT]; }
/** * 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; }
static function common_node_toolbar_buttons_sanitycheck(&$data, &$button_component, &$bind_object, &$calling_component) { if (!midcom::get('componentloader')->load_graceful($button_component)) { //For some reason the component is and can not (be) loaded debug_add("component {$button_component} could not be loaded", MIDCOM_LOG_ERROR); return false; } if (!array_key_exists('node', $data) || empty($data['node'])) { debug_add("data['node'] not given, trying with siteconfig", MIDCOM_LOG_DEBUG); $siteconfig = org_openpsa_core_siteconfig::get_instance(); $node_guid = $siteconfig->get_node_guid($button_component); if (!$node_guid) { debug_add("data['node'] not given, and {$button_component} could not be found in siteconfig", MIDCOM_LOG_INFO); return false; } $nap = new midcom_helper_nav(); $data['node'] = $nap->resolve_guid($node_guid); } if (empty($data['node'])) { //Invalid node given/found debug_add("data['node'] is invalid", MIDCOM_LOG_ERROR); return false; } $related_to = new org_openpsa_relatedto_dba(); $related_to->toGuid = $bind_object->guid; $related_to->toClass = get_class($bind_object); $related_to->toComponent = $calling_component; $related_to->fromComponent = $button_component; $related_to->status = org_openpsa_relatedto_dba::CONFIRMED; return $related_to; }
public static function get_url($attachment) { if (is_string($attachment)) { $guid = $attachment; $mc = self::new_collector('guid', $guid); $name = array_pop($mc->get_values('name')); } else { if (is_a($attachment, 'midcom_db_attachment')) { $guid = $attachment->guid; $name = $attachment->name; } else { throw new midcom_error('Invalid attachment identifier'); } } if ($GLOBALS['midcom_config']['attachment_cache_enabled']) { $subdir = substr($guid, 0, 1); if (file_exists($GLOBALS['midcom_config']['attachment_cache_root'] . '/' . $subdir . '/' . $guid . '_' . $name)) { return $GLOBALS['midcom_config']['attachment_cache_url'] . '/' . $subdir . '/' . $guid . '_' . urlencode($name); } } if (is_object($attachment)) { $nap = new midcom_helper_nav(); $parent = $nap->resolve_guid($attachment->parentguid); if (is_array($parent) && $parent[MIDCOM_NAV_TYPE] == 'node') { //Serve from topic return midcom_connection::get_url('self') . $parent[MIDCOM_NAV_RELATIVEURL] . urlencode($name); } } // Use regular MidCOM attachment server return midcom_connection::get_url('self') . 'midcom-serveattachmentguid-' . $guid . '/' . urlencode($name); }
/** * Determine the node that handles the DBA class and load the respective component */ private function _load_component_node() { $siteconfig = org_openpsa_core_siteconfig::get_instance(); $nap = new midcom_helper_nav(); $component = midcom::get('dbclassloader')->get_component_for_class($this->_dbaclass); midcom::get('componentloader')->load($component); $topic_guid = $siteconfig->get_node_guid($component); $this->_node = $nap->resolve_guid($topic_guid); if (!$this->_node) { throw new midcom_error("Could not load node information for topic {$topic_guid}. Last error was: " . midcom_connection::get_error_string()); } }
/** * Invalidates all cache objects related to the GUID specified. This function is aware for * NAP / Metadata caches. It will invalidate the node/leaf record pair upon each invalidation. * * This function only works within the current context, because it looks on the invalidated * GUID to handle the invalidation correctly. * * <b>Note, for GUIDs which cannot be resolved by NAP:</b> * * It should be safe to just skip this case, because if the object to be invalidated * cannot be found, it is not cached anyway (deleted items could be resolved using * the resolve_guid code which uses the cache, so they would still be found). * Special cases, where objects not available through NAP are updated have to be handled * by the component anyway. * * This way, leaf deletions should be safe in all cases (if they are cached, they can * still be resolved, if not, they aren't in the cache anyway). The Datamanager tries * to catch leaf creations using its internal creation mode flag, invalidating the * current content topic instead of the actual object in this case. Note, that this happens * directly after object creation, not during the regular safe cycle. * * See the automatic index invalidation code of the Datamanager for additional details. * * @todo Find a way to propagate leaf additions/deletions to a topic which must be invalidated in all * places necessary, or MIDCOM_NAV_LEAVES will be broken. * * @param string $guid The GUID to invalidate. */ function invalidate($guid) { $nav = new midcom_helper_nav(); $napobject = $nav->resolve_guid($guid); if ($napobject === false) { // Ignoring this should be safe, see the method documentation for details. debug_add("We failed to resolve the GUID {$guid} with NAP, apparently it is not cached or no valid NAP node, skipping it therefore.", MIDCOM_LOG_INFO); return; } if ($napobject[MIDCOM_NAV_TYPE] == 'leaf') { $cached_node_id = $napobject[MIDCOM_NAV_NODEID]; // Get parent from DB and compare to catch moves if ($parent = $napobject[MIDCOM_NAV_OBJECT]->get_parent()) { $parent_entry_from_object = $nav->resolve_guid($parent->guid); if ($parent_entry_from_object && $parent_entry_from_object[MIDCOM_NAV_ID] != $cached_node_id) { $this->_cache->remove($this->_prefix . '-' . $parent_entry_from_object[MIDCOM_NAV_ID] . '-leaves'); } } if (!empty($napobject[MIDCOM_NAV_GUID])) { $this->_cache->remove($this->_prefix . '-' . $napobject[MIDCOM_NAV_GUID]); } } else { $cached_node_id = $napobject[MIDCOM_NAV_ID]; //Invalidate subnode cache for the (cached) parent $parent_id = $napobject[MIDCOM_NAV_NODEID]; $parent_entry = $this->_cache->get("{$this->_prefix}-{$parent_id}"); if ($parent_entry && array_key_exists(MIDCOM_NAV_SUBNODES, $parent_entry)) { unset($parent_entry[MIDCOM_NAV_SUBNODES]); $this->_cache->put("{$this->_prefix}-{$parent_id}", $parent_entry); } //Cross-check parent value from object to detect topic moves if ($parent = $napobject[MIDCOM_NAV_OBJECT]->get_parent()) { $parent_entry_from_object = $nav->resolve_guid($parent->guid); if (!empty($parent_entry_from_object[MIDCOM_NAV_ID]) && !empty($parent_entry[MIDCOM_NAV_ID]) && $parent_entry_from_object[MIDCOM_NAV_ID] != $parent_entry[MIDCOM_NAV_ID]) { unset($parent_entry_from_object[MIDCOM_NAV_SUBNODES]); $this->_cache->put("{$this->_prefix}-{$parent_entry_from_object[MIDCOM_NAV_ID]}", $parent_entry_from_object); } } } $leaves_key = "{$cached_node_id}-leaves"; $this->_cache->remove("{$this->_prefix}-{$cached_node_id}"); $this->_cache->remove($this->_prefix . '-' . $napobject[MIDCOM_NAV_GUID]); $this->_cache->remove("{$this->_prefix}-{$leaves_key}"); }