protected function _runtemplate($template, $data = null) {
		if ($data === null) $data = $this->data;
		if (is_array($data)) $data = $this->data->customise($data);
		
		$viewer = SSViewer::fromString($template);
		return $viewer->process($data);
	}
 public function doSearch($gridField, $request)
 {
     $dataClass = $gridField->getList()->dataClass();
     $allList = $this->searchList ? $this->searchList : DataList::create($dataClass);
     $searchFields = $this->getSearchFields() ? $this->getSearchFields() : $this->scaffoldSearchFields($dataClass);
     if (!$searchFields) {
         throw new LogicException(sprintf('GridFieldAddExistingAutocompleter: No searchable fields could be found for class "%s"', $dataClass));
     }
     $params = array();
     foreach ($searchFields as $searchField) {
         $name = strpos($searchField, ':') !== FALSE ? $searchField : "{$searchField}:StartsWith";
         $params[$name] = $request->getVar('gridfield_relationsearch');
     }
     if (!$gridField->getList() instanceof UnsavedRelationList) {
         $allList = $allList->subtract($gridField->getList());
     }
     $results = $allList->filterAny($params)->sort(strtok($searchFields[0], ':'), 'ASC')->limit($this->getResultsLimit());
     $json = array();
     $originalSourceFileComments = Config::inst()->get('SSViewer', 'source_file_comments');
     Config::inst()->update('SSViewer', 'source_file_comments', false);
     foreach ($results as $result) {
         $json[$result->ID] = html_entity_decode(SSViewer::fromString($this->resultsFormat)->process($result));
     }
     Config::inst()->update('SSViewer', 'source_file_comments', $originalSourceFileComments);
     return Convert::array2json($json);
 }
 /**
  * Small helper to render templates from strings
  * Cloned from SSViewerTest
  */
 private function render($templateString, $data = null)
 {
     $t = SSViewer::fromString($templateString);
     if (!$data) {
         $data = new SSViewerTestFixture();
     }
     return $t->process($data);
 }
Example #4
0
    function testComments()
    {
        $viewer = SSViewer::fromString(<<<SS
This is my template<%-- this is a comment --%>This is some content<%-- this is another comment --%>This is the final content
SS
);
        $output = $viewer->process(new ArrayData(array()));
        $this->assertEquals("This is my templateThis is some contentThis is the final content", preg_replace("/\n?<!--.*-->\n?/U", '', $output));
    }
 /**
  * @return Array
  */
 public function getAttributes()
 {
     $attributes = array_merge(parent::getAttributes(), array('type' => 'hidden', 'data-searchurl' => $this->Link('search'), 'data-minimuminputlength' => $this->getConfig('minimumInputLength'), 'data-resultslimit' => $this->getConfig('resultsLimit'), 'data-placeholder' => $this->getConfig('placeholder'), 'data-multiple' => $this->getConfig('multiple')));
     if ($this->Value() && ($object = DataObject::get($this->getConfig('classToSearch'))->byID($this->Value()))) {
         $originalSourceFileComments = Config::inst()->get('SSViewer', 'source_file_comments');
         Config::inst()->update('SSViewer', 'source_file_comments', false);
         $attributes['data-selectioncontent'] = html_entity_decode(SSViewer::fromString($this->getConfig('selectionFormat'))->process($object));
         Config::inst()->update('SSViewer', 'source_file_comments', $originalSourceFileComments);
     }
     return $attributes;
 }
 function __construct($controller, $name, $class = 'Page', $limit = 30)
 {
     Requirements::javascript(ABC_PATH . '/javascript/child-list.js');
     Requirements::css(ABC_PATH . '/css/child-list.css');
     $do = new DataObject();
     $do->DataSet = AddPaginator::get($limit)->fetch($class, "SiteTree.ParentID = " . $controller->ID, "PublicationDate DESC, Created DESC");
     $do->Paginator = $do->DataSet->Paginator->dataForTemplate(null, null, '/admin/getitem?ID=' . $controller->ID);
     $parser = SSViewer::fromString(SSViewer::getTemplateContent('ChildList'));
     $str = $parser->process($do);
     parent::__construct($name, $str);
 }
 public function execute(WorkflowInstance $workflow)
 {
     $members = $workflow->getAssignedMembers();
     if (!$members || !count($members)) {
         return true;
     }
     $member = Member::currentUser();
     $initiator = $workflow->Initiator();
     $contextFields = $this->getContextFields($workflow->getTarget());
     $memberFields = $this->getMemberFields($member);
     $initiatorFields = $this->getMemberFields($initiator);
     $variables = array();
     foreach ($contextFields as $field => $val) {
         $variables["\$Context.{$field}"] = $val;
     }
     foreach ($memberFields as $field => $val) {
         $variables["\$Member.{$field}"] = $val;
     }
     foreach ($initiatorFields as $field => $val) {
         $variables["\$Initiator.{$field}"] = $val;
     }
     $pastActions = $workflow->Actions()->sort('Created DESC');
     $variables["\$CommentHistory"] = $this->customise(array('PastActions' => $pastActions, 'Now' => SS_Datetime::now()))->renderWith('CommentHistory');
     $from = str_replace(array_keys($variables), array_values($variables), $this->EmailFrom);
     $subject = str_replace(array_keys($variables), array_values($variables), $this->EmailSubject);
     if ($this->config()->whitelist_template_variables) {
         $item = new ArrayData(array('Initiator' => new ArrayData($initiatorFields), 'Member' => new ArrayData($memberFields), 'Context' => new ArrayData($contextFields), 'CommentHistory' => $variables["\$CommentHistory"]));
     } else {
         $item = $workflow->customise(array('Items' => $workflow->Actions(), 'Member' => $member, 'Context' => new ArrayData($contextFields), 'CommentHistory' => $variables["\$CommentHistory"]));
     }
     if ($this->ListingTemplateID) {
         $template = DataObject::get_by_id('ListingTemplate', $this->ListingTemplateID);
         $view = SSViewer::fromString($template->ItemTemplate);
     } else {
         $view = SSViewer::fromString($this->EmailTemplate);
     }
     $body = $view->process($item);
     foreach ($members as $member) {
         if ($member->Email) {
             $email = new Email();
             $email->setTo($member->Email);
             $email->setSubject($subject);
             $email->setFrom($from);
             $email->setBody($body);
             $email->send();
         }
     }
     return true;
 }
 public function execute(WorkflowInstance $workflow)
 {
     $email = new Email();
     $members = $workflow->getAssignedMembers();
     $emails = '';
     if (!$members || !count($members)) {
         return;
     }
     foreach ($members as $member) {
         if ($member->Email) {
             $emails .= "{$member->Email}, ";
         }
     }
     $context = $this->getContextFields($workflow->getTarget());
     $member = $this->getMemberFields();
     $variables = array();
     foreach ($context as $field => $val) {
         $variables["\$Context.{$field}"] = $val;
     }
     foreach ($member as $field => $val) {
         $variables["\$Member.{$field}"] = $val;
     }
     $subject = str_replace(array_keys($variables), array_values($variables), $this->EmailSubject);
     if ($this->ListingTemplateID) {
         $item = $workflow->customise(array('Items' => $workflow->Actions(), 'Member' => Member::currentUser(), 'Context' => $workflow->getTarget()));
         $template = DataObject::get_by_id('ListingTemplate', $this->ListingTemplateID);
         $view = SSViewer::fromString($template->ItemTemplate);
         $body = $view->process($item);
     } else {
         $body = str_replace(array_keys($variables), array_values($variables), $this->EmailTemplate);
     }
     $email->setSubject($subject);
     $email->setFrom($this->EmailFrom);
     $email->setBcc(substr($emails, 0, -2));
     $email->setBody($body);
     $email->send();
     return true;
 }
 /**
  * Returns a json array of a search results that can be used by for example Jquery.ui.autosuggestion
  *
  * @param GridField $gridField
  * @param SS_HTTPRequest $request 
  * @return sting in JSON fromat
  */
 public function doSearch($gridField, $request)
 {
     $dataClass = $gridField->getList()->dataClass();
     $allList = $this->searchList ? $this->searchList : DataList::create($dataClass);
     $searchFields = $this->getSearchFields() ? $this->getSearchFields() : $this->scaffoldSearchFields($dataClass);
     if (!$searchFields) {
         throw new LogicException(sprintf('GridFieldAddExistingAutocompleter: No searchable fields could be found for class "%s"', $dataClass));
     }
     // TODO Replace with DataList->filterAny() once it correctly supports OR connectives
     $stmts = array();
     foreach ($searchFields as $searchField) {
         $stmts[] .= sprintf('"%s" LIKE \'%s%%\'', $searchField, Convert::raw2sql($request->getVar('gridfield_relationsearch')));
     }
     $results = $allList->where(implode(' OR ', $stmts))->subtract($gridField->getList());
     $results = $results->sort($searchFields[0], 'ASC');
     $results = $results->limit($this->getResultsLimit());
     if (!empty($this->filters)) {
         $results = $results->addFilter($this->filters);
     }
     if (!empty($this->excludes)) {
         switch (count($this->excludes)) {
             case 1:
                 $key = key($this->excludes);
                 $results->exclude($key, $this->excludes[$key]);
                 break;
             case 2:
                 $results->exclude($this->excludes);
                 break;
             default:
                 throw new InvalidArgumentException('Incorrect number of arguments passed to filter()');
         }
     }
     $json = array();
     foreach ($results as $result) {
         $json[$result->ID] = SSViewer::fromString($this->resultsFormat)->process($result);
     }
     return Convert::array2json($json);
 }
 /**
  * Returns a json array of a search results that can be used by for example Jquery.ui.autosuggestion
  *
  * @param GridField $gridField
  * @param SS_HTTPRequest $request 
  */
 public function doSearch($gridField, $request)
 {
     $dataClass = $gridField->getList()->dataClass();
     $allList = DataList::create($dataClass);
     $filters = array();
     $stmts = array();
     $searchFields = $this->getSearchFields() ? $this->getSearchFields() : $this->scaffoldSearchFields($dataClass);
     if (!$searchFields) {
         throw new LogicException(sprintf('GridFieldAddExistingAutocompleter: No searchable fields could be found for class "%s"', $dataClass));
     }
     // TODO Replace with DataList->filterAny() once it correctly supports OR connectives
     foreach ($searchFields as $searchField) {
         $stmts[] .= 'LOWER(' . $searchField . ') LIKE \'%' . strtolower(Convert::raw2sql($request->getVar('gridfield_relationsearch'))) . '%\'';
     }
     $results = $allList->where(implode(' OR ', $stmts));
     $results = $results->sort($searchFields[0], 'ASC');
     $results = $results->limit($this->getResultsLimit());
     $json = array();
     foreach ($results as $result) {
         $json[$result->ID] = SSViewer::fromString($this->resultsFormat)->process($result);
     }
     return Convert::array2json($json);
 }
    /**
     * Gets the {@link FieldList} for editing the record
     * @return FieldList
     */
    public function getCMSFields()
    {
        // Requirements for Ace editor
        Requirements::javascript(PERMAMAIL_DIR . '/javascript/ace/ace.js');
        Requirements::javascript(PERMAMAIL_DIR . '/javascript/ace/theme-chrome.js');
        Requirements::javascript(PERMAMAIL_DIR . '/javascript/ace/mode-html.js');
        Requirements::javascript(PERMAMAIL_DIR . '/javascript/jquery-ace.js');
        Requirements::javascript(PERMAMAIL_DIR . '/javascript/ace-init.js');
        $fields = FieldList::create(TabSet::create("Root"));
        $fields->addFieldToTab('Root.Main', TextField::create('Identifier', 'Template name (no spaces, alphanumeric characters only)'));
        $fields->addFieldToTab('Root.Main', TextField::create('Subject', 'Default subject (optional)'));
        $fields->addFieldToTab('Root.Main', TextField::create('From', 'Default "from" address (optional)'));
        $fields->addFieldToTab('Root.Main', CheckboxField::create('IsAbstractTemplate', 'Is this an abstract template?<br>Abstract templates can be inherited by other templates. Useful for similar layout templates.'));
        $fields->addFieldToTab('Root.Main', DropdownField::create('ParentTemplate', 'Parent Abstract template. Useful for similar layout templates.', PermamailTemplate::get()->filter('IsAbstractTemplate', true)));
        $fields->addFieldToTab('Root.Main', TextareaField::create('Content', 'Template content')->addExtraClass('ace')->setRows(30)->setColumns(100)->setFieldHolderTemplate('PermamailTemplateEditor'));
        $vars = array();
        foreach ($this->TestVariables() as $v) {
            $value = $v->getVariableValue();
            $vars[$v->Variable] = $value ? $value : '';
        }
        // Populate the Content field with default Content from file template
        try {
            $content = SSViewer::fromString($this->getContent());
            $content = $content->process(new ViewableData(), $vars);
            if ($this->IsAbstractTemplate && $this->MainTemplate()->exists()) {
                $contentMain = SSViewer::fromString($this->MainTemplate()->getContent());
                $content = $contentMain->process(new ViewableData(), array('Content' => $content));
            }
        } catch (SSTemplateParseException $e) {
            $content = $e->getMessage();
        }
        $fields->addFieldToTab('Root.Main', new LabelField('ContentOutput', '<strong>Template Output</strong><br>
				<div style="background-color:white; padding: 1em; border: 3px solid grey;">' . $content . '</div><br>'), 'Content');
        $fields->addFieldsToTab("Root.Tests", array(EmailField::create('TestEmailAddress', 'Test email address'), GridField::create('TestVariables', 'Test variables', $this->TestVariables(), GridFieldConfig_RecordEditor::create())));
        return $fields;
    }
 /**
  * Replaces placeholders within the $content property their actual value
  *
  * @param string $content
  *
  * @return string
  */
 public function replacePlaceholders($content)
 {
     // Find placeholders
     preg_match_all("/{{(.*?)}}/", $this->owner->Content, $matches);
     // If placeholders found
     if (!empty($matches[1])) {
         // Fetch view templates
         $templates = DataObject::get('ViewTemplate')->filter(['Title' => $matches[1]])->getIterator();
         // Replace placeholders with their templates
         foreach ($matches[0] as $key => $templateHolder) {
             if ($templates->offsetExists($key)) {
                 // Remove <p> if TinyMCE added them
                 $content = str_replace('<p>' . $templateHolder . '</p>', $templateHolder, $content);
                 // Process the template
                 $template = SSViewer::fromString($templates->offsetGet($key)->ViewTemplate)->process($this->owner);
                 // Replace the placeholder with its template
                 $content = str_replace($templateHolder, $template, $content);
             }
         }
     }
     // Set and return content
     $this->owner->Content = $content;
     return $content;
 }
 /**
  * Returns a json array of a search results that can be used by for example Jquery.ui.autosuggestion
  *
  * @param GridField $gridField
  * @param SS_HTTPRequest $request 
  */
 public function doSearch($gridField, $request)
 {
     $dataClass = $gridField->getList()->dataClass();
     $allList = $this->searchList ? $this->searchList : DataList::create($dataClass);
     $searchFields = $this->getSearchFields() ? $this->getSearchFields() : $this->scaffoldSearchFields($dataClass);
     if (!$searchFields) {
         throw new LogicException(sprintf('GridFieldAddExistingAutocompleter: No searchable fields could be found for class "%s"', $dataClass));
     }
     $params = array();
     foreach ($searchFields as $searchField) {
         $name = strpos($searchField, ':') !== FALSE ? $searchField : "{$searchField}:StartsWith";
         $params[$name] = $request->getVar('gridfield_relationsearch');
     }
     $results = $allList->subtract($gridField->getList())->filterAny($params)->sort(strtok($searchFields[0], ':'), 'ASC')->limit($this->getResultsLimit());
     $json = array();
     foreach ($results as $result) {
         $json[$result->ID] = SSViewer::fromString($this->resultsFormat)->process($result);
     }
     return Convert::array2json($json);
 }
Example #14
0
	/**
	 * Load all the template variables into the internal variables, including
	 * the template into body.  Called before send() or debugSend()
	 * $isPlain=true will cause the template to be ignored, otherwise the GenericEmail template will be used
	 * and it won't be plain email :) 
	 */
	protected function parseVariables($isPlain = false) {
		if(!$this->parseVariables_done) {
			$this->parseVariables_done = true;

			// Parse $ variables in the base parameters
			$data = $this->templateData();
			
			foreach(array('from','to','subject','body', 'plaintext_body', 'cc', 'bcc') as $param) {
				$template = SSViewer::fromString($this->$param);
				$this->$param = $template->process($data);
			}
			
			// Process a .SS template file
			$fullBody = $this->body;
			if($this->ss_template && !$isPlain) {
				// Requery data so that updated versions of To, From, Subject, etc are included
				$data = $this->templateData();
				
				$template = new SSViewer($this->ss_template);
				
				if($template->exists()) {
					$fullBody = $template->process($data);
				}
			}
			
			// Rewrite relative URLs
			$this->body = HTTP::absoluteURLs($fullBody);
		}
	}
 public function Content()
 {
     if (!$this->ID) {
         return '';
     }
     $action = Controller::has_curr() ? Controller::curr()->getRequest()->latestParam('Action') : null;
     if ($this->ComponentFilterName && !$action) {
         // For a list of relations like tags/categories/etc
         $items = $this->ComponentListingItems();
         $item = $this->customise(array('Items' => $items));
         $view = SSViewer::fromString($this->ComponentListingTemplate()->ItemTemplate);
     } else {
         $items = $this->ListingItems();
         $item = $this->customise(array('Items' => $items));
         $view = SSViewer::fromString($this->ListingTemplate()->ItemTemplate);
     }
     $content = str_replace('<p>$Listing</p>', '$Listing', $this->Content);
     return str_replace('$Listing', $view->process($item), $content);
 }
 /**
  * Return the results with a template applied to them based on the page's listing template
  *
  */
 public function TemplatedResults()
 {
     $query = $this->owner->data()->getQuery();
     if ($this->owner->data()->ListingTemplateID && $query) {
         $template = DataObject::get_by_id('ListingTemplate', $this->owner->data()->ListingTemplateID);
         if ($template && $template->exists()) {
             $items = $query ? $query->getDataObjects() : new DataObjectSet();
             $item = $this->owner->data()->customise(array('Items' => $items));
             $view = SSViewer::fromString($template->ItemTemplate);
             return $view->process($item);
         }
     }
 }
 /**
  * Get string value of HTML body with all variable evaluated.
  *
  * @param SiteConfig $config
  * @param array List of safe template variables to expose to this template
  *
  * @return HTMLText
  */
 protected function getEmailBody($config, $variables, $type)
 {
     if ($type == "reminder1") {
         $template = SSViewer::fromString($config->ReviewBodyFirstReminder);
     }
     if ($type == "reminder2") {
         $template = SSViewer::fromString($config->ReviewBodySecondReminder);
     }
     if ($type == "due") {
         $template = SSViewer::fromString($config->ReviewBody);
     }
     $value = $template->process(new ArrayData($variables));
     // Cast to HTML
     return DBField::create_field('HTMLText', (string) $value);
 }
 protected function getTestTemplate()
 {
     return SSViewer::fromString('A=$a, B=$b, C.E=$c.e, D.H=$d.h, E=<% loop e %>$a<% end_loop %>');
 }
 public function renderClusterInformationBubble($stationIDList, $extraParam = null, $templateName = '')
 {
     // multiple stations, render list
     $obj = new ArrayList();
     $obj = $this->getFeature($stationIDList, $extraParam);
     foreach ($obj as $item) {
         $item->classname = "content_" . str_replace('.', '_', $item->FeatureID);
     }
     $data = new ArrayData(array("items" => $obj, "count" => $obj->Count()));
     if ($this->UseTemplateForPopupWindow) {
         $template = $this->Popup_ClusterInformation;
         $viewer = SSViewer::fromString($template);
         return $viewer->process($data);
     }
     // @to2: deprecate this
     $listItemTemplate = 'Station: $FeatureID';
     if ($this->ClusterAttributes) {
         $listItemTemplate = $this->ClusterAttributes;
     }
     // 1st partial template: create template for content area
     $template = '<% loop items %>';
     $template .= sprintf('<li><a onClick="multipleStationSelect(\'$FeatureID\');return false;">%s</a></li><div class=\'$classname\'></div>', $listItemTemplate);
     $template .= '<%  end_loop %>';
     // 2nd partial template: create template for header area
     $header = 'There are $count Items.';
     if ($this->ClusterPopupHeader) {
         $header = $this->ClusterPopupHeader;
     }
     // render partial tempates
     $viewer = SSViewer::fromString($header);
     $clusterPopupHeader = $viewer->process($data);
     $viewer = SSViewer::fromString($template);
     $stationListTemplate = $viewer->process($data);
     // render combined tempate
     $out = new ViewableData();
     $out->customise(array("stationList" => $stationListTemplate, "PopupHeader" => $clusterPopupHeader));
     return $out->renderWith('MapPopup_List');
 }
 public function RequireCustomTemplatedJS($template)
 {
     $template = str_replace('<script>', '', $template);
     $template = str_replace('</script>', '', $template);
     $template = SSViewer::fromString($template);
     $result = $template->process($this->owner);
     Requirements::customScript($result);
 }
 function notifyError($type, $fields = null)
 {
     list($subject, $body) = self::$errors[$type];
     $subject = self::$error_email_subject_prefix . $subject;
     $body = self::$error_email_body_prefix . $body . self::$error_email_body_suffix;
     if ($fields) {
         if (!is_array($fields)) {
             $fields = array($fields);
         }
         $this->owner->AndFieldNames = implode(' and ', $fields);
         $this->owner->OrFieldNames = "'" . implode("' or '", $fields) . "'";
     }
     $parser = SSViewer::fromString($subject);
     $subject = $parser->process($this->owner);
     $parser = SSViewer::fromString($body);
     $body = $parser->process($this->owner);
     $from = self::$error_email_from;
     if (!$from) {
         $from = Email::getAdminEmail();
     }
     $to = self::$error_email_to;
     if (!$to) {
         $to = Email::getAdminEmail();
     }
     $email = new Email($from, $to, $subject, $body);
     $email->send();
 }
 public function Content()
 {
     $items = $this->ListingItems();
     $item = $this->customise(array('Items' => $items));
     $view = SSViewer::fromString($this->ListingTemplate()->ItemTemplate);
     $content = str_replace('<p>$Listing</p>', '$Listing', $this->Content);
     return str_replace('$Listing', $view->process($item), $content);
 }
	/**
	 * Gets called recursively on the child-objects of the chain.
	 * 
	 * @param array $nestingLevels see {@buildNestedUL}
	 * @param int $level Current nesting level
	 * @param string $template Template for list item
	 * @param string $ulExtraAttributes Extra attributes
	 * @return string
	 */
	public function getChildrenAsUL($nestingLevels, $level = 0, $template = "<li id=\"record-\$ID\" class=\"\$EvenOdd\">\$Title", $ulExtraAttributes = null, &$itemCount = 0) {
		$output = "";
		$hasNextLevel = false;
		$ulExtraAttributes = " $ulExtraAttributes";
		$output = "<ul" . eval($ulExtraAttributes) . ">\n";

		$currentNestingLevel = $nestingLevels[$level];

		// either current or default template
		$currentTemplate = (!empty($currentNestingLevel)) ? $currentNestingLevel['template'] : $template;
		$myViewer = SSViewer::fromString($currentTemplate);

		if(isset($nestingLevels[$level+1]['dataclass'])){
			$childrenMethod = $nestingLevels[$level+1]['dataclass'];
		}
		// sql-parts

		$filter = (isset($nestingLevels[$level+1]['filter'])) ? $nestingLevels[$level+1]['filter'] : null;
		$sort = (isset($nestingLevels[$level+1]['sort'])) ? $nestingLevels[$level+1]['sort'] : null;
		$join = (isset($nestingLevels[$level+1]['join'])) ? $nestingLevels[$level+1]['join'] : null;
		$limit = (isset($nestingLevels[$level+1]['limit'])) ? $nestingLevels[$level+1]['limit'] : null;
		$having = (isset($nestingLevels[$level+1]['having'])) ? $nestingLevels[$level+1]['having'] : null;

		foreach($this as $parent) {
			$evenOdd = ($itemCount % 2 == 0) ? "even" : "odd";
			$parent->setField('EvenOdd', $evenOdd);
			$template = $myViewer->process($parent);

			// if no output is selected, fall back to the id to keep the item "clickable"
			$output .= $template . "\n";

			if(isset($childrenMethod)) {
				// workaround for missing groupby/having-parameters in instance_get
				// get the dataobjects for the next level
				$children = $parent->$childrenMethod($filter, $sort, $join, $limit, $having);
				if($children) {
					$output .= $children->getChildrenAsUL($nestingLevels, $level+1, $currentTemplate, $ulExtraAttributes);
				}
			}
			$output .= "</li>\n";
			$itemCount++;
		}

		$output .= "</ul>\n";

		return $output;
	}
 /**
  * Process and render search results (taken from @Link ContentControllerSearchExtension with slightly altered parameters).
  *
  * @param array $data The raw request data submitted by user
  * @param SearchForm $form The form instance that was submitted
  */
 public function getSearchResults($data = null, $form = null)
 {
     // Keep track of the search time taken.
     $startTime = microtime(true);
     // Don't allow searching without a valid search engine.
     $engine = $this->data()->SearchEngine;
     $fulltext = Config::inst()->get('FulltextSearchable', 'searchable_classes');
     if (is_null($engine) || $engine === 'Full-Text' && (!is_array($fulltext) || count($fulltext) === 0)) {
         return $this->httpError(404);
     }
     // Attempt to retrieve the results for the current search engine extension.
     if ($engine !== 'Full-Text' && $this->extension_instances) {
         $extension = "{$engine}Search_Controller";
         foreach ($this->extension_instances as $instance) {
             if (get_class($instance) === $extension) {
                 $instance->setOwner($this);
                 if (method_exists($instance, 'getSearchResults')) {
                     // Keep track of the search time taken, for the current search engine extension.
                     $startTime = microtime(true);
                     $customisation = $instance->getSearchResults($data, $form);
                     $output = $this->customise($customisation)->renderWith(array("{$engine}Search_results", "{$engine}SearchPage_results", 'ExtensibleSearch_results', 'ExtensibleSearchPage_results', 'Page_results', "{$engine}Search", "{$engine}SearchPage", 'ExtensibleSearch', 'ExtensibleSearchPage', 'Page'));
                     $totalTime = microtime(true) - $startTime;
                     // Log the details of a user search for analytics.
                     $this->service->logSearch($data['Search'], isset($customisation['Results']) && ($results = $customisation['Results']) ? count($results) : 0, $totalTime, $engine, $this->data()->ID);
                     return $output;
                 }
                 $instance->clearOwner();
                 break;
             }
         }
     }
     // Fall back to displaying the full-text results.
     $searchable = Config::inst()->get('FulltextSearchable', 'searchable_classes');
     if (is_null($sort = $this->data()->SortBy)) {
         $sort = 'Relevance';
     }
     $direction = $this->data()->SortDir === 'Ascending' ? 'ASC' : 'DESC';
     // Apply any site tree restrictions.
     $filter = implode(', ', $this->SearchTrees()->map('ID', 'ID')->toArray());
     if ($filter) {
         $filter = "ParentID IN({$filter})";
     }
     $results = is_array($searchable) && count($searchable) > 0 && $form ? $form->getExtendedResults($this->data()->ResultsPerPage, "{$sort} {$direction}", $filter, $data) : null;
     // Render the full-text results using a listing template where defined.
     if ($this->data()->ListingTemplateID && $results) {
         $template = DataObject::get_by_id('ListingTemplate', $this->data()->ListingTemplateID);
         if ($template && $template->exists()) {
             $render = $this->data()->customise(array('Items' => $results));
             $viewer = SSViewer::fromString($template->ItemTemplate);
             $results = $viewer->process($render);
         }
     }
     // Render everything into the search page template.
     $customisation = array('Results' => $results, 'Query' => $form ? $form->getSearchQuery() : null, 'Title' => _t('ExtensibleSearchPage.SearchResults', 'Search Results'));
     $output = $this->customise($customisation)->renderWith(array('ExtensibleSearch_results', 'ExtensibleSearchPage_results', 'Page_results', 'ExtensibleSearch', 'ExtensibleSearchPage', 'Page'));
     $totalTime = microtime(true) - $startTime;
     // Log the details of a user search for analytics.
     $this->service->logSearch($data['Search'], $results ? count($results) : 0, $totalTime, $engine, $this->data()->ID);
     return $output;
 }
Example #25
0
 /**
  * See {@link ViewableDataTest} for more extensive casting tests,
  * this test just ensures that basic casting is correctly applied during template parsing.
  */
 public function testCastingHelpers()
 {
     $vd = new SSViewerTest_ViewableData();
     $vd->TextValue = '<b>html</b>';
     $vd->HTMLValue = '<b>html</b>';
     $vd->UncastedValue = '<b>html</b>';
     // Value casted as "Text"
     $this->assertEquals('&lt;b&gt;html&lt;/b&gt;', $t = SSViewer::fromString('$TextValue')->process($vd));
     $this->assertEquals('<b>html</b>', $t = SSViewer::fromString('$TextValue.RAW')->process($vd));
     $this->assertEquals('&lt;b&gt;html&lt;/b&gt;', $t = SSViewer::fromString('$TextValue.XML')->process($vd));
     // Value casted as "HTMLText"
     $this->assertEquals('<b>html</b>', $t = SSViewer::fromString('$HTMLValue')->process($vd));
     $this->assertEquals('<b>html</b>', $t = SSViewer::fromString('$HTMLValue.RAW')->process($vd));
     $this->assertEquals('&lt;b&gt;html&lt;/b&gt;', $t = SSViewer::fromString('$HTMLValue.XML')->process($vd));
     // Uncasted value (falls back to ViewableData::$default_cast="HTMLText")
     $vd = new SSViewerTest_ViewableData();
     // TODO Fix caching
     $vd->UncastedValue = '<b>html</b>';
     $this->assertEquals('<b>html</b>', $t = SSViewer::fromString('$UncastedValue')->process($vd));
     $vd = new SSViewerTest_ViewableData();
     // TODO Fix caching
     $vd->UncastedValue = '<b>html</b>';
     $this->assertEquals('<b>html</b>', $t = SSViewer::fromString('$UncastedValue.RAW')->process($vd));
     $vd = new SSViewerTest_ViewableData();
     // TODO Fix caching
     $vd->UncastedValue = '<b>html</b>';
     $this->assertEquals('&lt;b&gt;html&lt;/b&gt;', $t = SSViewer::fromString('$UncastedValue.XML')->process($vd));
 }
 /**
  * Returns a json array of a search results that can be used by for
  * example Jquery.ui.autosuggestion
  *
  * @param GridField $gridField
  * @param SS_HTTPRequest $request
  */
 public function doSearch($gridField, $request)
 {
     $product_class = $this->getSourceClass();
     $params = array();
     // Do we have filter fields setup?
     if ($this->getAutocompleteFields()) {
         $search_fields = $this->getAutocompleteFields();
     } else {
         $search_fields = $this->scaffoldSearchFields($product_class);
     }
     if (!$search_fields) {
         throw new LogicException(sprintf('GridFieldAddExistingAutocompleter: No searchable fields could be found for class "%s"', $product_class));
     }
     foreach ($search_fields as $search_field) {
         $name = strpos($search_field, ':') !== false ? $search_field : "{$search_field}:StartsWith";
         $params[$name] = $request->getVar('gridfieldaddbydbfield');
     }
     $results = DataList::create($product_class)->filterAny($params)->sort(strtok($search_fields[0], ':'), 'ASC')->limit($this->getResultsLimit());
     $json = array();
     $originalSourceFileComments = Config::inst()->get('SSViewer', 'source_file_comments');
     Config::inst()->update('SSViewer', 'source_file_comments', false);
     foreach ($results as $result) {
         $json[$result->ID] = html_entity_decode(SSViewer::fromString($this->results_format)->process($result));
     }
     Config::inst()->update('SSViewer', 'source_file_comments', $originalSourceFileComments);
     return Convert::array2json($json);
 }
 /**
  * Process an SS template as string so that it can access $EditableTextField_6746f values
  */
 public function processTemplateMarkup($ssMarkup, $data = array())
 {
     $submission = $this->owner->Submission();
     if (!$submission || !$submission->exists()) {
         return null;
     }
     $data = array('Values' => $submission->Values());
     foreach ($submission->Values() as $record) {
         $data[$record->Name] = $record->getFormattedValue();
     }
     return DBField::create_field('HTMLText', SSViewer::fromString($ssMarkup)->process($this->owner->customise($data)));
 }
    function testBaseTagGeneration()
    {
        // XHTML wil have a closed base tag
        $tmpl1 = SSViewer::fromString('<?xml version="1.0" encoding="UTF-8"?>
			<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
			<html>
				<head><% base_tag %></head>
				<body><p>test</p><body>
			</html>');
        $this->assertRegExp('/<head><base href=".*" \\/><\\/head>/', $tmpl1->process(new ViewableData()));
        // HTML4 and 5 will only have it for IE
        $tmpl2 = SSViewer::fromString('<!DOCTYPE html>
			<html>
				<head><% base_tag %></head>
				<body><p>test</p><body>
			</html>');
        $this->assertRegExp('/<head><base href=".*"><!--\\[if lte IE 6\\]><\\/base><!\\[endif\\]--><\\/head>/', $tmpl2->process(new ViewableData()));
        $tmpl3 = SSViewer::fromString('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
			<html>
				<head><% base_tag %></head>
				<body><p>test</p><body>
			</html>');
        $this->assertRegExp('/<head><base href=".*"><!--\\[if lte IE 6\\]><\\/base><!\\[endif\\]--><\\/head>/', $tmpl3->process(new ViewableData()));
        // Check that the content negotiator converts to the equally legal formats
        $negotiator = new ContentNegotiator();
        $response = new SS_HTTPResponse($tmpl1->process(new ViewableData()));
        $negotiator->html($response);
        $this->assertRegExp('/<head><base href=".*"><!--\\[if lte IE 6\\]><\\/base><!\\[endif\\]--><\\/head>/', $response->getBody());
        $response = new SS_HTTPResponse($tmpl1->process(new ViewableData()));
        $negotiator->xhtml($response);
        $this->assertRegExp('/<head><base href=".*" \\/><\\/head>/', $response->getBody());
    }
Example #29
0
 /**
  * Execute the evaluated string, passing it the given data.
  * Used by partial caching to evaluate custom cache keys expressed using
  * template expressions
  * 
  * @param string $content Input string
  * @param mixed $data Data context
  * @param array $arguments Additional arguments
  * @return string Evaluated result
  */
 public static function execute_string($content, $data, $arguments = null)
 {
     $v = SSViewer::fromString($content);
     $v->includeRequirements(false);
     return $v->process($data, $arguments);
 }
 /**
  * Overload the Email::parseVariables() method to use a user-defined template
  * @param  boolean $isPlain
  * @return Permamail
  */
 public function parseVariables($isPlain = false)
 {
     $origState = Config::inst()->get('SSViewer', 'source_file_comments');
     Config::inst()->update('SSViewer', 'source_file_comments', false);
     $userTemplate = $this->getUserTemplate();
     if (!$this->parseVariables_done) {
         $this->parseVariables_done = true;
         // Parse $ variables in the base parameters
         $data = $this->templateData();
         // Process a .SS template file
         $fullBody = $this->body;
         if ($userTemplate || $this->ss_template && !$isPlain) {
             // Requery data so that updated versions of To, From, Subject, etc are included
             $data = $this->templateData();
             $template = $userTemplate ? SSViewer::fromString($userTemplate->Content) : new SSViewer($this->ss_template);
             if ($template instanceof SSViewer_FromString || $template->exists()) {
                 $fullBody = $template->process($data);
             }
         }
         // Rewrite relative URLs
         $this->body = HTTP::absoluteURLs($fullBody);
     }
     Config::inst()->update('SSViewer', 'source_file_comments', $origState);
     return $this;
 }