Overview

Namespaces

  • None
  • PHP

Classes

  • Breadcrumb
  • Breadcrumbs
  • CacheFile
  • Comment
  • CommentArray
  • CommentFilter
  • CommentForm
  • CommentList
  • Config
  • Database
  • DatabaseQuery
  • DatabaseQuerySelect
  • DatabaseQuerySelectFulltext
  • DatabaseStopwords
  • Debug
  • Field
  • Fieldgroup
  • Fieldgroups
  • FieldgroupsArray
  • Fields
  • FieldsArray
  • Fieldtype
  • FieldtypeMulti
  • Fieldtypes
  • FileLog
  • FilenameArray
  • Fuel
  • HookEvent
  • ImageSizer
  • Inputfield
  • InputfieldsArray
  • InputfieldWrapper
  • Language
  • LanguageParser
  • Languages
  • LanguagesPageFieldValue
  • LanguageSupportInstall
  • LanguageTranslator
  • Markdown_Parser
  • MarkdownExtra_Parser
  • ModuleJS
  • ModulePlaceholder
  • Modules
  • Notice
  • NoticeError
  • NoticeMessage
  • Notices
  • NullPage
  • Page
  • PageArray
  • Pagefile
  • Pagefiles
  • PagefilesManager
  • PageFinder
  • Pageimage
  • Pageimages
  • PagerNav
  • PagerNavItem
  • Pages
  • PagesAccess
  • PagesSortfields
  • PagesType
  • Paths
  • Permission
  • Permissions
  • Process
  • ProcessController
  • ProcessWire
  • Role
  • Roles
  • Sanitizer
  • Selector
  • SelectorBitwiseAnd
  • SelectorContains
  • SelectorContainsLike
  • SelectorContainsWords
  • SelectorEnds
  • SelectorEqual
  • SelectorGreaterThan
  • SelectorGreaterThanEqual
  • SelectorLessThan
  • SelectorLessThanEqual
  • SelectorNotEqual
  • Selectors
  • SelectorStarts
  • Session
  • SessionCSRF
  • SmartyPants_Parser
  • SmartyPantsTypographer_Parser
  • SystemUpdate1
  • Template
  • TemplateFile
  • Templates
  • TemplatesArray
  • Textformatter
  • Textile
  • User
  • Users
  • Wire
  • WireArray
  • WireData
  • WireInput
  • WireInputData
  • WireSaveableItems
  • WireSaveableItemsLookup
  • WireUpload

Interfaces

  • CommentFormInterface
  • CommentListInterface
  • ConfigurableModule
  • FieldtypeLanguageInterface
  • FieldtypePageTitleCompatible
  • HasLookupItems
  • HasRoles
  • InputfieldHasArrayValue
  • Module
  • Saveable
  • TrackChanges

Exceptions

  • ProcessController404Exception
  • ProcessControllerPermissionException
  • Wire404Exception
  • WireDatabaseException
  • WireException
  • WirePermissionException

Functions

  • __
  • _n
  • _x
  • fuel
  • identify_modifier_markdown
  • Markdown
  • mdwp_add_p
  • mdwp_hide_tags
  • mdwp_show_tags
  • mdwp_strip_p
  • ProcessWireClassLoader
  • ProcessWireHostSiteConfig
  • ProcessWireShutdown
  • removeNewlines
  • SmartDashes
  • SmartEllipsis
  • SmartQuotes
  • smarty_modifier_markdown
  • smarty_modifier_smartypants
  • SmartyPants
  • tabIndent
  • unregisterGLOBALS
  • wire
  • wireDecodeJSON
  • wireEncodeJSON
  • wireMkdir
  • Overview
  • Namespace
  • Class
  • Tree
  • Download
  1: <?php
  2: 
  3: /**
  4:  * ProcessWire Templates
  5:  *
  6:  * Manages and provides access to all the Template instances
  7:  * 
  8:  * ProcessWire 2.x 
  9:  * Copyright (C) 2010 by Ryan Cramer 
 10:  * Licensed under GNU/GPL v2, see LICENSE.TXT
 11:  * 
 12:  * http://www.processwire.com
 13:  * http://www.ryancramer.com
 14:  *
 15:  */
 16: 
 17: /**
 18:  * WireArray of Template instances
 19:  *
 20:  */
 21: class TemplatesArray extends WireArray {
 22: 
 23:     public function isValidItem($item) {
 24:         return $item instanceof Template;   
 25:     }
 26: 
 27:     public function isValidKey($key) {
 28:         return is_int($key) || ctype_digit($key); 
 29:     }
 30: 
 31:     public function getItemKey($item) {
 32:         return $item->id; 
 33:     }
 34: 
 35:     public function makeBlankItem() {
 36:         return new Template();
 37:     }
 38: 
 39: }
 40: 
 41: /**
 42:  * Manages and provides access to all the Template instances
 43:  *
 44:  */
 45: class Templates extends WireSaveableItems {
 46: 
 47:     /**
 48:      * Reference to all the Fieldgroups
 49:      *
 50:      */
 51:     protected $fieldgroups = null; 
 52: 
 53:     /**
 54:      * WireArray of all Template instances
 55:      *
 56:      */
 57:     protected $templatesArray; 
 58: 
 59:     /**
 60:      * Path where Template files are stored
 61:      *
 62:      */
 63:     protected $path; 
 64: 
 65:     /**
 66:      * Construct the Templates
 67:      *
 68:      * @param Fieldgroups $fieldgroups Reference to the Fieldgroups
 69:      * @param string $path Path to where template files are stored
 70:      *
 71:      */
 72:     public function __construct(Fieldgroups $fieldgroups, $path) {
 73:         $this->fieldgroups = $fieldgroups; 
 74:         $this->templatesArray = new TemplatesArray();
 75:         $this->path = $path;
 76:     }
 77: 
 78:     /**
 79:      * Initialize the TemplatesArray and populate
 80:      *
 81:      */
 82:     public function init() {
 83:         $this->load($this->templatesArray); 
 84:     }
 85: 
 86:     /**
 87:      * Return the WireArray that this DAO stores it's items in
 88:      *
 89:      */
 90:     public function getAll() {
 91:         return $this->templatesArray;
 92:     }
 93: 
 94:     /**
 95:      * Return a new blank item 
 96:      *
 97:      */
 98:     public function makeBlankItem() {
 99:         return new Template(); 
100:     }
101: 
102:     /**
103:      * Return the name of the table that this DAO stores item records in
104:      *
105:      */
106:     public function getTable() {
107:         return 'templates';
108:     }
109: 
110:     /**
111:      * Return the field name that fields should initially be sorted by
112:      *
113:      */
114:     public function getSort() {
115:         return $this->getTable() . ".name";
116:     }
117: 
118:     /**
119:      * Given a template ID or name, return the matching template or NULL if not found.
120:      *
121:      */
122:     public function get($key) {
123:         if($key == 'path') return $this->path;
124:         $value = $this->templatesArray->get($key); 
125:         if(is_null($value)) $value = parent::get($key);
126:         return $value; 
127:     }
128: 
129: 
130:     /**
131:      * Update or insert template to database 
132:      *
133:      * If the template's fieldgroup has changed, then we delete data that's no longer applicable to the new fieldgroup. 
134:      *
135:      */
136:     public function ___save(Saveable $item) {
137: 
138:         $isNew = $item->id < 1; 
139: 
140:         if(!$item->fieldgroup->id) throw new WireException("You must save Fieldgroup '{$item->fieldgroup}' before adding to Template '{$item}'"); 
141: 
142:         $rolesChanged = $item->isChanged('useRoles');
143: 
144:         if($this->fuel('pages')->get("/")->template->id == $item->id) {
145:             if(!$item->useRoles) throw new WireException("Template '{$item}' is used by the homepage and thus must manage access"); 
146:             if(!$item->hasRole("guest")) throw new WireException("Template '{$item}' is used by the homepage and thus must have the 'guest' role assigned."); 
147:         }
148: 
149:         $result = parent::___save($item); 
150: 
151:         if($result && !$isNew && $item->fieldgroupPrevious && $item->fieldgroupPrevious->id != $item->fieldgroup->id) {
152:             // the fieldgroup has been changed
153:             // remove data from all fields that are not part of the new fieldgroup
154:             $removeFields = new FieldsArray();
155:             foreach($item->fieldgroupPrevious as $field) {
156:                 if(!$item->fieldgroup->has($field)) {
157:                     $removeFields->add($field); 
158:                 }
159:             }
160:             if(count($removeFields)) { 
161:                 $pages = $this->fuel('pages')->find("templates_id={$item->id}, check_access=0, status<" . Page::statusMax); 
162:                 foreach($pages as $page) {
163:                     foreach($removeFields as $field) {
164:                         $field->type->deletePageField($page, $field); 
165:                         if($this->fuel('config')->debug) $this->message("Removed field '$field' on page '{$page->url}'"); 
166:                     }
167:                 }
168:             }
169:         }
170: 
171:         if($rolesChanged) { 
172:             $access = new PagesAccess();
173:             $access->updateTemplate($item); 
174:         }
175: 
176:         return $result; 
177:     }
178: 
179:     /**
180:      * Delete a template and unset it from this object. 
181:      *
182:      */
183:     public function ___delete(Saveable $item) {
184:         if($item->flags & Template::flagSystem) throw new WireException("Can't delete template '{$item->name}' because it is a system template."); 
185:         $cnt = $item->getNumPages();
186:         if($cnt > 0) throw new WireException("Can't delete template '{$item->name}' because it is used by $cnt pages.");  
187: 
188:         return parent::___delete($item);
189:     }
190: 
191:     /**
192:      * Create and return a cloned copy of this template
193:      *
194:      * Note that this also clones the Fieldgroup if the template being cloned has it's own named fieldgroup.
195:      *
196:      * @param Saveable $item Item to clone
197:      * @param bool|Saveable $item Returns the new clone on success, or false on failure
198:      *
199:      */
200:     public function ___clone(Saveable $item) {
201: 
202:         $original = $item;
203:         $item = clone $item; 
204: 
205:         if($item->flags & Template::flagSystem) {
206:             // we want to avoid creating clones that have system flags
207:             $item->flags = $item->flags | Template::flagSystemOverride; 
208:             $item->flags = $item->flags & ~Template::flagSystem;
209:             $item->flags = $item->flags & ~Template::flagSystemOverride;
210:         }
211: 
212:         $item->id = 0; // note this must be after removing system flags
213: 
214:         $fieldgroup = $item->fieldgroup; 
215: 
216:         if($fieldgroup->name == $item->name) {
217:             // if the fieldgroup and the item have the same name, we'll also clone the fieldgroup
218:             $fieldgroup = wire('fieldgroups')->clone($fieldgroup);  
219:             $item->fieldgroup = $fieldgroup;
220:         }
221: 
222:         $item = parent::___clone($item);
223: 
224:         if($item && $item->id && !$item->altFilename) { 
225:             // now that we have a clone, lets also clone the template file, if it exists
226:             $path = $this->fuel('config')->paths->templates; 
227:             $file = $path . $item->name . '.' . $this->fuel('config')->templateExtension; 
228:             if($original->filenameExists() && is_writable($path) && !file_exists($file)) { 
229:                 if(copy($original->filename, $file)) $item->filename = $file;
230:             }
231:         }
232: 
233:         return $item;
234:     }
235: 
236: 
237:     /**
238:      * Return the number of pages using the provided Template
239:      *
240:      */
241:     public function getNumPages(Template $tpl) {
242:         $result = $this->fuel('db')->query("SELECT COUNT(*) AS total FROM pages WHERE templates_id={$tpl->id}"); 
243:         $row = $result->fetch_assoc(); 
244:         $result->free();
245:         return (int) $row['total'];
246:     }
247: 
248:     /**
249:      * Overridden from WireSaveableItems to retain specific keys
250:      *
251:      */
252:     protected function encodeData(array $value) {
253:         return wireEncodeJSON($value, array('slashUrls'));  
254:     }
255: 
256: }
257: 
258: 
ProcessWire API documentation generated by ApiGen 2.6.0