Index: DEVELOPER.txt =================================================================== RCS file: DEVELOPER.txt diff -N DEVELOPER.txt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ DEVELOPER.txt 3 Sep 2007 04:20:58 -0000 @@ -0,0 +1,37 @@ +/* $Id$ */ + +DEVELOPER INFORMATION +--------------------- + +Inline module heavily relies on hook_filter() and hook_nodeapi() of Drupal core. +It is important to know and understand the processing steps of these hooks. + +HOOK_NODEAPI() operations + +view: load view alter + +edit: load prepare + +preview: load prepare validate load view alter + +save: prepare validate submit insert + +update: load prepare validate submit update + + +Modifications to a node are only possible in operations + +- prepare +- submit +- view +- alter. + +Additional information: + +- Modifications in view and alter should affect $node->content. +- Operation view is processed in front of input filtering. +- In operation alter, the fields below $node->content contain already filtered + contents. +- Operations insert and update do not allow to modify a node's content. The + basic node information has already been stored in the database at this point. + Index: inline.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/inline/inline.module,v retrieving revision 1.19.2.8 diff -u -p -r1.19.2.8 inline.module --- inline.module 24 Aug 2007 00:41:55 -0000 1.19.2.8 +++ inline.module 3 Sep 2007 04:41:04 -0000 @@ -167,7 +167,7 @@ function inline_filter($op, $delta = 0, return $text; case 'process': - return $text; + return _inline_substitute_tags($text); } } @@ -204,38 +204,125 @@ function inline_filter_tips($delta, $for /** * Implementation of hook_nodeapi(). * - * Substitutes Inline tags with the corresponding files or images in front of - * node_view(). + * Adds/updates/removes the Inline node information tag required by + * inline_filter(). * Replaces numeric file references in Inline tags (i.e. [inline:1]) with named * file references (i.e. [inline:foo.jpg]) upon node preview and node save. * + * @todo Node preview does not work. + * @todo Node insert does not work. + * @todo Check if there are attachments by upload or CCK file-/imagefields. * @todo Break processing at all if Inline filter is not enabled. */ function inline_nodeapi(&$node, $op, $arg) { - if (!is_array($node->files)) { - return; - } switch ($op) { case 'alter': case 'print': - // Only nodes with Inline filter in the format may be processed. - foreach (filter_list_format($node->format) as $filter) { - if ($filter->module == 'inline') { - $node->teaser = _inline_substitute_tags($node, 'teaser'); - $node->body = _inline_substitute_tags($node, 'body'); - break; - } - } if (variable_get('upload_inline_'. $node->type, 0)) { $node = _inline_auto_add($node); } return; case 'prepare': + // Remove Inline info tag in front of displaying node edit form. + _inline_filter_info($node, 'remove'); + // Replace numeric file references with filenames. + $node->teaser = _inline_replace_numbers($node, 'teaser'); + $node->body = _inline_replace_numbers($node, 'body'); + return; + + case 'validate': + // Attempt to fix node form preview 03/09/2007 sun + _inline_filter_info($node, 'add'); + return; + case 'submit': + // Add Inline info tag to existing nodes. + _inline_filter_info($node, 'add'); + // Replace numeric file references with filenames. $node->teaser = _inline_replace_numbers($node, 'teaser'); $node->body = _inline_replace_numbers($node, 'body'); return; + + case 'insert': + // Problem: Node API does not provide an operation to alter node contents + // instantly before inserting a node into the database. We need the node + // id for our Inline info tag. + // Possible solution: Determine all textfields with Inline as allowed + // input format, add our Inline info tag and invoke a node update right + // after inserting the node. Problematic: Node revisions. + // Alternative: Try to manually update corresponding fields in the + // database. + // 03/09/2007 sun + return; + + case 'update': + _inline_filter_info($node, 'update'); + return; + + case 'view': + // Attempt to fix node form preview 03/09/2007 sun + _inline_filter_info($node, 'add'); + return; + } +} + +/** + * Add or remove an Inline info tag to or from all textfields of a node. + * + * @param object|string $node + * A node object to process, passed by reference. + * @param string $op + * An operation to perform, 'add', 'update', 'remove' or 'process'. If $op is + * 'remove' or 'process', $node has to be a string. + * + * @return array + * If $op is 'process', an array containing the Inline info tag values is + * returned. + * + * @todo Determine all textfields (incl. CCK) to process. + */ +function _inline_filter_info(&$node, $op) { + $regexp = '/\[inline-info\|([^\]]+)\]/'; + $tag = '[inline-info|timestamp='. time() .'|nid='. $node->nid .']'; + + $textfields = array('teaser', 'body'); + + switch ($op) { + case 'add': + foreach ($textfields as $field) { + $node->$field = $tag . $node->$field; + } + break; + + case 'update': + foreach ($textfields as $field) { + $node->$field = preg_replace($regexp, $tag, $node->$field); + } + break; + + case 'remove': + if (is_object($node)) { + foreach ($textfields as $field) { + $node->$field = preg_replace($regexp, '', $node->$field); + } + } + else { + $node = preg_replace($regexp, '', $node); + } + break; + + case 'process': + preg_match($regexp, $node, $match); + if (!empty($match[1])) { + $params = explode('|', $match[1]); + $info = array(); + foreach ($params as $param) { + $param = explode('=', $param); + $info[$param[0]] = $param[1]; + } + } + return $info; } } @@ -420,16 +507,25 @@ function _inline_auto_add($node) { /** * Replace all Inline tags with their corresponding files or images. * - * @param object $node - * The node to process. - * @param string $field - * The node field to process. + * @param string $text + * A content to process. * * @return string - * The processed content of the given node field. + * The processed content. */ -function _inline_substitute_tags(&$node, $field) { - if (preg_match_all("/\[(inline|file|attachment):([^=\\]]+)=?([^\\]]*)?\]/i", $node->$field, $match)) { +function _inline_substitute_tags($text) { + // Retrieve parent object information of this content. + $info = _inline_filter_info($text, 'process'); + _inline_filter_info($text, 'remove'); + + if (preg_match_all("/\[(inline|file|attachment):([^=\\]]+)=?([^\\]]*)?\]/i", $text, $match)) { + if (isset($info['nid']) && (int)$info['nid'] > 0) { + $node = node_load($info['nid']); + } + else { + return $text; + } + $s = $r = array(); foreach ($match[2] as $key => $value) { // Ensure that we deal with a file object. @@ -455,9 +551,9 @@ function _inline_substitute_tags(&$node, $r[] = $replace; } // Perform the replacements and return processed field. - return str_replace($s, $r, $node->$field); + return str_replace($s, $r, $text); } - return $node->$field; + return $text; } /** @@ -475,7 +571,7 @@ function _inline_replace_numbers($node, $tag = '/\[(inline|file|attachment):(\d+?)(=.+?)?\]/i'; // Look if there are any numeric inline tags. preg_match_all($tag, $node->$field, $matches, PREG_SET_ORDER); - if (!empty($matches)) { + if (!empty($matches) && !empty($node->files)) { foreach ($matches as $match) { // The array key of the attachment is the file ID (fid). $filekeys = array_keys($node->files);