protected function processTemplateBlocks(Template $template, &$globals, RendererInterface $renderer)
 {
     if ($this->benchmarkRendering) {
         $this->Benchmark->start('process-template-blocks-' . $template->getName());
     }
     $templateBlocks = $template->getTemplateBlocks();
     $data = $template->getData();
     $locals = $template->getLocals();
     $handler = $template->getContentType() != 'html' && $template->getContentType() != '' ? $template->getContentType() . '-' : '';
     $renderout = '';
     $contents = '';
     $parsedContents = '';
     $locals['DisplayRecords'] = sizeof($data);
     $locals['Count'] = 1;
     if (!empty($data)) {
         //if(LOG_ENABLE) System::log(self::$logType, 'Parsing contents block');
         if (!isset($templateBlocks[$handler . 'contents']) && !isset($templateBlocks[$handler . 'header']) && !isset($templateBlocks[$handler . 'exec'])) {
             throw new Exception('Template [' . $template->getName() . '] is missing a template block for [' . $handler . 'contents] or [' . $handler . 'header] or [' . $handler . 'exec]');
         }
         $eBlock = isset($templateBlocks[$handler . 'exec']) ? $templateBlocks[$handler . 'exec'] : '';
         $cBlock = isset($templateBlocks[$handler . 'contents']) ? $templateBlocks[$handler . 'contents'] : '';
         $ciBlock = isset($templateBlocks[$handler . 'contents-inbetween']) ? $templateBlocks[$handler . 'contents-inbetween'] : '';
         if (!empty($eBlock)) {
             $contents = $eBlock;
             $contents = $this->parseSetters($contents, $locals);
             $contents = $this->parseConditions($contents, $locals);
             $contents = $this->parseFilters($contents, $locals);
             $contents = $this->parseAssets($contents, $locals);
             // parse dependent sub modules
             $template->setLocals($locals);
             // $this->Logger->debug("Parsing dependent includes for [{$template->getName()}]...");
             $contents = $this->parseTemplateIncludes($contents, $template->getContentType(), $template, $globals, $renderer, false, true);
             $contents = $this->parseFormatVariables($contents, $locals);
             $renderout .= $contents;
         } else {
             // List Processing of the Data
             foreach ((array) $data as $row) {
                 $contents = $cBlock;
                 // if(strpos($contents, '{% set ') !== FALSE) {
                 //     while(preg_match("/(.*?)\{\%\s+set\s+([^\%]+?)\s+\%\}\s*(.*?)\s?\{\%\s+endset\s+\%\}\s*(.*)/s",$contents,$m)) {
                 //         if(!array_key_exists($m[2], $row)) {
                 //             $val = $this->parseFormatVariablesAndFilters($m[3], $row);
                 //             $row[$m[2]] = $val;
                 //         }
                 //         $contents = $m[1]. $m[4];
                 //      }
                 // }
                 if ($locals['DisplayRecords'] != $locals['Count']) {
                     $contents .= $ciBlock;
                 }
                 if (!is_array($row)) {
                     if ($row instanceof Node) {
                         /*
                          * Populating Node itself into the row so it can be used in templates,
                          * passed to events, filters, etc.  see ticket #30
                          * todo: investigate populating 'Node' in populateNodeCheaters directly
                          */
                         $node = $row;
                         $row = $this->NodeMapper->populateNodeCheaters($row)->toArray();
                         $row['Node'] = $node;
                     } else {
                         if ($row instanceof Object) {
                             $row = $row->toArray();
                         } else {
                             throw new Exception("data is not an array\n" . print_r($row, true));
                         }
                     }
                 }
                 $row_locals = array_merge($locals, $row);
                 $row_locals['SerializedData'] = $row;
                 //if(LOG_ENABLE) System::log(self::$logType, 'Locals ['.print_r($locals, true).']');
                 $contents = $this->parseSetters($contents, $row_locals);
                 $contents = $this->parseConditions($contents, $row_locals);
                 $contents = $this->parseFilters($contents, $row_locals);
                 $contents = $this->parseAssets($contents, $row_locals);
                 // parse dependent sub modules
                 $template->setLocals($row_locals);
                 // $this->Logger->debug("Parsing dependent includes for [{$template->getName()}]...");
                 $contents = $this->parseTemplateIncludes($contents, $template->getContentType(), $template, $globals, $renderer, false, true);
                 $contents = $this->parseFormatVariables($contents, $row_locals);
                 $locals['Count']++;
                 $parsedContents .= $contents;
             }
             $locals = $row_locals;
             $template->setLocals($locals);
             // headers and footers can use format variables from the final row
             $renderout = '';
             if (!empty($templateBlocks[$handler . 'header'])) {
                 $header = $templateBlocks[$handler . 'header'];
                 $header = $this->parseSetters($header, $locals);
                 $header = $this->parseConditions($header, $locals);
                 $header = $this->parseFilters($header, $locals);
                 $header = $this->parseAssets($header, $locals);
                 $template->setLocals($locals);
                 // parse dependent sub modules
                 $header = $this->parseTemplateIncludes($header, $template->getContentType(), $template, $globals, $renderer, false, true);
                 $header = $this->parseFormatVariables($header, $locals);
                 $renderout .= $header;
             }
             $renderout .= $parsedContents;
             if (!empty($templateBlocks[$handler . 'footer'])) {
                 $footer = $templateBlocks[$handler . 'footer'];
                 $footer = $this->parseSetters($footer, $locals);
                 $footer = $this->parseConditions($footer, $locals);
                 $footer = $this->parseFilters($footer, $locals);
                 $footer = $this->parseAssets($footer, $locals);
                 $template->setLocals($locals);
                 // parse dependent sub modules
                 $footer = $this->parseTemplateIncludes($footer, $template->getContentType(), $template, $globals, $renderer, false, true);
                 $footer = $this->parseFormatVariables($footer, $locals);
                 $renderout .= $footer;
             }
         }
     } else {
         if (!$template->isTopTemplate() && !array_key_exists($handler . 'contents', $templateBlocks) && !array_key_exists($handler . 'noresults', $templateBlocks)) {
             throw new Exception('Template [' . $template->getName() . '] is missing a template block for [' . $handler . 'noresults] or [' . $handler . 'contents] or [' . $handler . 'exec]');
         }
         if (array_key_exists($handler . 'noresults', $templateBlocks)) {
             $renderout = $templateBlocks[$handler . 'noresults'];
         } elseif ($template->getData() === null && empty($locals['DataSource']) && array_key_exists($handler . 'exec', $templateBlocks)) {
             $renderout = $templateBlocks[$handler . 'exec'];
         } elseif ($template->getData() === null && empty($locals['DataSource']) && array_key_exists($handler . 'contents', $templateBlocks)) {
             $renderout = $templateBlocks[$handler . 'contents'];
         } elseif ($template->isTopTemplate()) {
             throw new NotFoundException($template->getName());
         }
         $renderout = $this->parseSetters($renderout, $locals);
         $renderout = $this->parseConditions($renderout, $locals);
         $renderout = $this->parseFilters($renderout, $locals);
         $renderout = $this->parseConditions($renderout, $locals);
         $template->setLocals($locals);
         // parse dependent sub modules
         //$template->setLocals($locals);
         $renderout = $this->parseTemplateIncludes($renderout, $template->getContentType(), $template, $globals, $renderer, false, true);
         $renderout = $this->parseFormatVariables($renderout, $locals);
     }
     //if(LOG_ENABLE) System::log(self::$logType, 'Render out ['.print_r($renderout, true).']');
     if ($this->benchmarkRendering) {
         $this->Benchmark->end('process-template-blocks-' . $template->getName());
     }
     return $renderout;
 }
 /**
  * Returns a cacheKey for the specified Template
  *
  * @param Template $template The template to generate the cacheKey for
  * @param array    $globals  An array of globals set on this template
  *
  * @return string The cache key
  */
 public function getTemplateCacheKey(Template $template, $globals)
 {
     $locals = $template->getLocals();
     $cachekey = '';
     if ($template->isTopTemplate()) {
         $cachekey .= $this->Request->getAdjustedRequestURI();
     } else {
         $cachekey .= $template->getContentType() . $template->getName();
     }
     $cacheParams = array();
     // any locals that aren't globals
     foreach ($locals as $name => $value) {
         if (!is_array($value) && !array_key_exists($name, $globals) && !preg_match("/^[A-Z\\-\\_0-9]+\$/", $name) && !preg_match("/\\-\\d+\$/", $name)) {
             $cacheParams[$name] = $value;
         }
     }
     if (isset($cacheParams['UseQueryStringInCacheKey']) && StringUtils::strToBool($cacheParams['UseQueryStringInCacheKey']) == true) {
         foreach ($_GET as $name => $value) {
             if (!is_array($value)) {
                 $cacheParams['q_' . $name] = $value;
             }
         }
     }
     $cachekey .= '?';
     if (!empty($cacheParams)) {
         ksort($cacheParams);
         foreach ($cacheParams as $n => $v) {
             $cachekey .= $n . '=' . substr($v, 0, 255) . '&';
         }
     }
     $cachekey = rtrim($cachekey, '&');
     $this->Logger->debug('Cache Key [' . $cachekey . ']');
     return $cachekey;
 }
    public function testTemplateSetContentUsingCollectionExtracts()
    {
        $obj = new Template();
        $subject = <<<EOD
{
    "collection": {
        "href": "http://www.ovagraph.com/api/3/users/123",
        "items": [
            {
                "data": [
                    {
                        "name": "uid",
                        "value": "123"
                    },
                    {
                        "name": "user",
                        "value": "lsmith"
                    },
                    {
                        "name": "mail",
                        "value": "*****@*****.**"
                    },
                    {
                        "name": "first",
                        "value": "Linda"
                    },
                    {
                        "name": "last",
                        "value": "Smith"
                    },
                    {
                        "name": "timezone",
                        "value": "Pacific/Tahiti"
                    },
                    {
                        "name": "created",
                        "value": "1393010987"
                    },
                    {
                        "name": "temp_units",
                        "value": "f"
                    },
                    {
                        "name": "cl",
                        "value": 28
                    },
                    {
                        "name": "devices",
                        "value": [
                            {
                                "id": "02FFFF00",
                                "name": "Fairhaven Health Mobile Adapter",
                                "type": 2
                            }
                        ]
                    }
                ],
                "href": "http://www.ovagraph.com/api/3/users/123",
                "links": [
                    {
                        "href": "http://www.ovagraph.com/user/123",
                        "name": "about",
                        "prompt": "More info",
                        "rel": "about",
                        "render": "link"
                    }
                ]
            }
        ],
        "template": {
            "data": [
                {
                    "name": "user",
                    "prompt": "Username",
                    "value": "lsmith"
                },
                {
                    "name": "pass",
                    "prompt": "Password",
                    "value": "secret"
                },
                {
                    "name": "mail",
                    "prompt": "E-mail address",
                    "value": "*****@*****.**"
                },
                {
                    "name": "first",
                    "prompt": "First Name",
                    "value": "Linda"
                },
                {
                    "name": "last",
                    "prompt": "Last Name",
                    "value": "Smith"
                },
                {
                    "name": "devices",
                    "prompt": "Devices",
                    "value": [
                        {
                            "id": "02FFFF00",
                            "type": 2
                        }
                    ]
                },
                {
                    "name": "timezone",
                    "prompt": "Time zone",
                    "value": "Pacific/Tahiti"
                },
                {
                    "name": "temp_units",
                    "prompt": "Preferred Temperature Units",
                    "value": "f"
                },
                {
                    "name": "cl",
                    "prompt": "Average Cycle Length (in OvaCue)",
                    "value": "28"
                }
            ]
        },
        "version": "1.0"
    }
}
EOD;
        $return = $obj->setContent($subject);
        $this->assertInstanceOf('\\AKlump\\Http\\CollectionJson\\Template', $return);
        $dataArray = $obj->getDataArray();
        $this->assertCount(9, $dataArray);
        $this->assertSame('application/vnd.collection+json', $obj->getContentType());
    }