changed git call from https to git readonly
[atutor.git] / mods / phpdoc / PHPDoc / redist / ITX.php
1 <?php
2 /**
3 * Integrated Template Extension - ITX
4 *
5 * With this class you get the full power of the phplib template class. 
6 * You may have one file with blocks in it but you have as well one main file 
7 * and multiple files one for each block. This is quite usefull when you have
8 * user configurable websites. Using blocks not in the main template allows
9 * you to some parts of your layout easily. 
10 *
11 * Note that you can replace an existing block and add new blocks add runtime.
12 * Adding new blocks means changing a variable placeholder to a block.
13 *
14 * @author       Ulf Wendel <uw@netuse.de>
15 * @access               public
16 * @version      $ID: $
17 * @package      PHPDoc
18 */
19 class IntegratedTemplateExtension extends IntegratedTemplate {
20
21         /**
22         * Array with all warnings.
23         * @var          array
24         * @access       public
25         * @see          $printWarning, $haltOnWarning, warning()
26         */
27         var $warn = array();
28         
29         /**
30         * Print warnings?
31         * @var          array
32         * @access       public
33         * @see          $haltOnWarning, $warn, warning()
34         */
35         var $printWarning = false;
36         
37         /**
38         * Call die() on warning?
39         * @var          boolean
40         * @access       public
41         * @see          $warn, $printWarning, warning()
42         */
43         var $haltOnWarning = false;
44                 
45         /**
46         * RegExp used to test for a valid blockname.
47         * @var  string
48         */      
49         var $checkblocknameRegExp = "";
50         
51         /**
52         * Builds some complex regexps and calls the constructor of the parent class.
53         *
54         * Make sure that you call this constructor if you derive you own 
55         * template class from this one.
56         *
57         * @see  IntegratedTemplate()
58         */
59         function IntegratedTemplateExtension() {
60         
61                 $this->checkblocknameRegExp = "@".$this->blocknameRegExp."@";
62                 $this->IntegratedTemplate();
63                                                                                                                                                                                         
64         } // end func IntegratedTemplateExtension
65         
66         /**
67         * Replaces an existing block with new content. Warning: not implemented yet.
68         * 
69         * The Replacement does not affect previously added variables. All data is cached.
70         * In case the new block does contain less or other variable placeholder the previously
71         * passed data that is no longer referenced will be deleted. The internal list 
72         * of allowed variables gets updated as well.
73         *
74         * In case the original block contains other blocks it must eighter have placeholder
75         * for the inner blocks or contain them. If you want to use placeholder the placeholder must
76         * look like openingDelimiter."__".blockname."__".closingDelimiter .
77         *
78         * Due to the cache updates replaceBlock() and replaceBlockfile() are "expensive" operations 
79         * which means extensive usage will slow down your script. So try to avoid them and if 
80         * you can't do so try to use them before you pass lots of variables to the block you're 
81         * replacing.
82         * 
83         * @param        string  Blockname
84         * @param        string  Blockcontent
85         * @return       boolean 
86         * @see          replaceBlockfile(), addBlock(), addBlockfile()
87         * @access       public
88         */
89         function replaceBlock($block, $template) {
90                 if (!isset($this->blocklist[$block])) {
91                         $this->halt("The block '$block' does not exist in the template and thus it can't be replaced.", __FILE__, __LINE__);
92                         return false;
93                 }
94                 if (""==$template) {
95                         $this->halt("No block content given.", __FILE__, __LINE__);
96                         return false;
97                 }
98                 
99                 print "This function has not been coded yet.";
100                 
101                 // find inner blocks
102                 // add to variablelist
103                 // compare variable list
104                 // update caches
105                 
106                 return true;
107         } // end func replaceBlock
108         
109         /**
110         * Replaces an existing block with new content from a file. Warning: not implemented yet.
111         * @brother replaceBlock()
112         * @param        string  Blockname
113         * @param        string  Name of the file that contains the blockcontent
114         */
115         function replaceBlockfile($block, $filename) {
116                 return $this->replaceBlock($block, $this->getFile($filename));  
117         } // end func replaceBlockfile
118         
119         /**
120         * Adds a block to the template changing a variable placeholder to a block placeholder.
121         *
122         * Add means "replace a variable placeholder by a new block". 
123         * This is different to PHPLibs templates. The function loads a 
124         * block, creates a handle for it and assigns it to a certain 
125         * variable placeholder. To to the same with PHPLibs templates you would 
126         * call set_file() to create the handle and parse() to assign the
127         * parsed block to a variable. By this PHPLibs templates assume that you tend
128         * to assign a block to more than one one placeholder. To assign a parsed block
129         * to more than only the placeholder you specify in this function you have
130         * to use a combination of getBlock() and setVariable().
131         *
132         * As no updates to cached data is necessary addBlock() and addBlockfile() 
133         * are rather "cheap" meaning quick operations.
134         *
135         * The block content must not start with <!-- BEGIN blockname --> and end with 
136         * <!-- END blockname --> this would cause overhead and produce an error.
137         * 
138         * @param        string  Name of the variable placeholder, the name must be unique within the template.
139         * @param        string  Name of the block to be added
140         * @param        string  Content of the block
141         * @return       boolean
142         * @see          addBlockfile()
143         * @access       public
144         */      
145         function addBlock($placeholder, $blockname, $template) {
146         
147                 // Don't trust any user even if it's a programmer or yourself...
148                 if (""==$placeholder) {
149                 
150                         $this->halt("No variable placeholder given.", __FILE__, __LINE__);
151                         return false;
152                         
153                 }       else if (""==$blockname || !preg_match($this->checkblocknameRegExp, $blockname) ) {
154                         
155                         print $this->checkblocknameRegExp;
156                         $this->halt("No or invalid blockname '$blockname' given.", __FILE__, __LINE__);
157                         return false;
158                         
159                 } else if (""==$template) {
160                 
161                         $this->halt("No block content given.", __FILE__, __LINE__);
162                         return false;
163                         
164                 } else if (isset($this->blocklist[$blockname])) {
165                 
166                         $this->halt("The block already exists.", __FILE__, __LINE__);
167                         return false;
168                         
169                 }
170                 
171                 // Hmm, we should do some more tests.
172                 $parents = $this->findPlaceholderBlocks($placeholder);
173                 if (0==count($parents)) {
174                 
175                         $this->halt("The variable placeholder '$placeholder' was not found in the template.", __FILE__, __LINE__);
176                         return false;
177                         
178                 } else if ( count($parents)>1 ) {
179                         
180                         reset($parents);
181                         while (list($k, $parent)=each($parents)) 
182                                 $msg.= "$parent, ";
183                         $msg = substr($parent, -2);
184                         
185                         $this->halt("The variable placeholder '$placeholder' must be unique, found in multiple blocks '$msg'.", __FILE__, __LINE__);
186                         return false;
187                                                 
188                 }
189                 
190                 $template = "<!-- BEGIN $blockname -->".$template."<!-- END $blockname -->";
191                 $this->findBlocks($template);
192                 if ($this->flagBlocktrouble) 
193                         return false;   // findBlocks() already throws an exception
194                 
195                 $this->blockinner[$parents[0]][] = $blockname;
196                 $this->blocklist[$parents[0]] = preg_replace(   "@".$this->openingDelimiter.$placeholder.$this->closingDelimiter."@", 
197                                                                                                                                                                                                         $this->openingDelimiter."__".$blockname."__".$this->closingDelimiter, 
198                                                                                                                                                                                                         $this->blocklist[$parents[0]]
199                                                                                                                                                                                                 );
200                                                                                                                                                                                                 
201                 $this->deleteFromBlockvariablelist($parents[0], $placeholder);
202                 $this->updateBlockvariablelist($blockname);
203                 
204                 return true;
205         } // end func addBlock
206         
207         /**
208         * Adds a block taken from a file to the template changing a variable placeholder to a block placeholder. 
209         * 
210         * @param                string  Name of the variable placeholder to be converted
211         * @param                string  Name of the block to be added
212         * @param                string  File that contains the block
213         * @brother      addBlock()
214         */
215         function addBlockfile($placeholder, $blockname, $filename) {
216                 return $this->addBlock($placeholder, $blockname, $this->getFile($filename));
217         } // end func addBlockfile
218         
219         /**
220         * Deletes one or many variables from the block variable list.
221         * @param        string  Blockname
222         * @param        mixed           Name of one variable or array of variables ( array ( name => true ) ) to be stripped.
223         */
224         function deleteFromBlockvariablelist($block, $variables) {
225         
226                 if (!is_array($variables))
227                         $variables = array( $variables => true);
228                         
229                 reset($this->blockvariables[$block]);
230                 while (list($k, $varname)=each($this->blockvariables[$block])) 
231                         if (isset($variables[$varname])) 
232                                 unset($this->blockvariables[$block][$k]);
233                                         
234         } // end deleteFromBlockvariablelist
235
236         /**
237         * Updates the variable list of a block.
238         * @param        string  Blockname
239         */      
240         function updateBlockvariablelist($block) {
241                 
242                 preg_match_all( $this->variablesRegExp, $this->blocklist[$block], $regs );
243                 $this->blockvariables[$block] = $regs[1];
244                         
245         } // end func updateBlockvariablelist
246         
247         /**
248         * Returns an array of blocknames where the given variable placeholder is used.
249         * @param        string  Variable placeholder
250         * @return       array   $parents        parents[0..n] = blockname
251         */
252         function findPlaceholderBlocks($variable) {
253                 
254                 $parents = array();
255                 
256                 reset($this->blocklist);
257                 while (list($blockname, $content)=each($this->blocklist)) {
258                         
259                         reset($this->blockvariables[$blockname]);
260                         while (list($k, $varname)=each($this->blockvariables[$blockname]))
261                                 if ($variable == $varname) 
262                                         $parents[] = $blockname;
263                 }
264                         
265                 return $parents;
266         } // end func findPlaceholderBlocks
267
268         /**
269         * Handles warnings, saves them to $warn and prints them or calls die() depending on the flags
270         * @param        string  Warning
271         * @param        string  File where the warning occured
272         * @param        int                     Linenumber where thr warning occured
273         * @see          $warn, $printWarning, $haltOnWarning
274         */
275         function warning($message, $file="", $line=0) {
276                 
277                 $message = sprintf("IntegratedTemplateExtension Warning: %s [File: %s, Line: %d]",
278                                                                                                         $message,
279                                                                                                         $file, 
280                                                                                                         $line );
281
282                 $this->warn[] = $message;
283                 
284                 if ($this->printWarning)
285                         print $message;
286                         
287                 if ($this->haltOnError) 
288                         die($message);
289                 
290         } // end func warning
291         
292 } // end class IntegratedTemplateExtension
293 ?>