Ejemplo n.º 1
0
 public function find_all_tags_and_repeaters($type = 'content', $contents = false)
 {
     $template = $this->template;
     $path = $this->file;
     if ($contents === false) {
         $contents = $this->load();
     }
     $untouched_content = $contents;
     $out = array();
     // Excluded tags are discarded
     $tag_pairs_to_exclude = array();
     $tag_pairs_with_empty_openers = array('blocks');
     //	List of tags to process. Blocks needs to come before others, as blocks can contain e.g. repeaters.
     $tag_pairs_to_process = array('blocks', 'repeater');
     if (PERCH_RUNWAY) {
         $tag_pairs_to_process[] = 'related';
     }
     // Add excluded tags so they can be discarded.
     $tag_pairs_to_process = array_merge($tag_pairs_to_process, $tag_pairs_to_exclude);
     foreach ($tag_pairs_to_process as $tag_type) {
         // parse out tag pairs
         $empty_opener = in_array($tag_type, $tag_pairs_with_empty_openers);
         $close_tag = '</perch:' . $tag_type . '>';
         $close_tag_len = mb_strlen($close_tag);
         $open_tag = '<perch:' . $tag_type . ($empty_opener ? '' : ' ');
         $order = 1;
         // escape hatch
         $i = 0;
         $max_loops = 100;
         // loop through while we have closing tags
         while ($close_pos = mb_strpos($contents, $close_tag)) {
             // we always have to go from the start, as the string length changes,
             // but stop at the closing tag
             $chunk = mb_substr($contents, 0, $close_pos);
             // search from the back of the chunk for the opening tag
             $open_pos = mb_strrpos($chunk, $open_tag);
             // get the pair html chunk
             $len = $close_pos + $close_tag_len - $open_pos;
             $pair_html = mb_substr($contents, $open_pos, $len);
             // find the opening tag - it's right at the start
             $opening_tag_end_pos = mb_strpos($pair_html, '>') + 1;
             $opening_tag = mb_substr($pair_html, 0, $opening_tag_end_pos);
             // condition contents
             $condition_contents = mb_substr($pair_html, $opening_tag_end_pos, 0 - $close_tag_len);
             // Do the business
             $OpeningTag = new PerchXMLTag($opening_tag);
             $tmp = array();
             if ($tag_type == 'repeater') {
                 $Repeater = new PerchRepeater($OpeningTag->attributes);
                 $Repeater->set('id', $OpeningTag->id());
                 //$Repeater->tags = $this->find_all_tags($type, $condition_contents);
                 $Repeater->tags = $this->find_all_tags_and_repeaters($type, $condition_contents);
                 $tmp['tag'] = $Repeater;
             } elseif ($tag_type == 'blocks') {
                 $OpeningTag->set('id', '_blocks');
                 $OpeningTag->set('type', 'PerchBlocks');
                 $tmp['tag'] = $OpeningTag;
             } else {
                 $tmp['tag'] = $OpeningTag;
             }
             // Set the order
             if ($OpeningTag->order()) {
                 $tmp['order'] = (int) $OpeningTag->order();
             } else {
                 $tmp['order'] = strpos($untouched_content, $opening_tag);
             }
             // If the tag isn't one to strip/exclude, add it to the list.
             if (!in_array($tag_type, $tag_pairs_to_exclude)) {
                 $out[] = $tmp;
             }
             // Remove the pair so we can parse the next one
             $contents = str_replace($pair_html, '', $contents);
             // escape hatch counter
             $i++;
             if ($i > $max_loops) {
                 return $contents;
             }
         }
     }
     $s = '/<perch:(' . $type . '|categories)[^>]*>/';
     $count = preg_match_all($s, $contents, $matches);
     if ($count > 0) {
         $i = 100;
         if (is_array($matches[0])) {
             foreach ($matches[0] as $match) {
                 $tmp = array();
                 $tmp['tag'] = new PerchXMLTag($match);
                 if (!in_array('categories', $this->disabled_features)) {
                     if ($tmp['tag']->tag_name() == 'perch:categories') {
                         $tmp['tag']->set('type', 'category');
                     }
                 }
                 if ($tmp['tag']->tag_name() == 'perch:related') {
                     $tmp['tag']->set('type', 'related');
                 }
                 if ($tmp['tag']->type() != 'repeater') {
                     if ($tmp['tag']->order()) {
                         $tmp['order'] = (int) $tmp['tag']->order();
                     } else {
                         $tmp['order'] = strpos($untouched_content, $match);
                         #PerchUtil::debug('Setting order to: '.$tmp['order']);
                         $i++;
                     }
                     $out[] = $tmp;
                 }
             }
         }
     }
     if (PerchUtil::count($out)) {
         // sort tags using 'order' attribute
         $out = PerchUtil::array_sort($out, 'order');
         $final = array();
         foreach ($out as $tag) {
             $final[] = $tag['tag'];
         }
         return $final;
     }
     return false;
 }