Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * HTML original framed output converter, modified to use Smarty Template.
4
 * This Converter takes output from the {@link Parser} and converts it to HTML-ready output for use with {@link Smarty}.
5
 *
6
 * phpDocumentor :: automatic documentation generator
7
 *
8
 * PHP versions 4 and 5
9
 *
10
 * Copyright (c) 2002-2006 Gregory Beaver
11
 *
12
 * LICENSE:
13
 *
14
 * This library is free software; you can redistribute it
15
 * and/or modify it under the terms of the GNU Lesser General
16
 * Public License as published by the Free Software Foundation;
17
 * either version 2.1 of the License, or (at your option) any
18
 * later version.
19
 *
20
 * This library is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23
 * Lesser General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU Lesser General Public
26
 * License along with this library; if not, write to the Free Software
27
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28
 *
29
 * @package    Converters
30
 * @subpackage HTMLframes
31
 * @author     Gregory Beaver <cellog@php.net>
32
 * @copyright  2002-2006 Gregory Beaver
33
 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
34
 * @version    CVS: $Id: HTMLframesConverter.inc 234145 2007-04-19 20:20:57Z ashnazg $
35
 * @filesource
36
 * @link       http://www.phpdoc.org
37
 * @link       http://pear.php.net/PhpDocumentor
38
 * @see        parserDocBlock, parserInclude, parserPage, parserClass
39
 * @see        parserDefine, parserFunction, parserMethod, parserVar
40
 * @since      1.2
41
 */
42
/**
43
 * HTML output converter.
44
 * This Converter takes output from the {@link Parser} and converts it to HTML-ready output for use with {@link Smarty}.
45
 *
46
 * @package Converters
47
 * @subpackage HTMLframes
48
 * @see parserDocBlock, parserInclude, parserPage, parserClass, parserDefine, parserFunction, parserMethod, parserVar
49
 * @author Greg Beaver <cellog@php.net>
50
 * @since 1.2
51
 * @version $Id: HTMLframesConverter.inc 234145 2007-04-19 20:20:57Z ashnazg $
52
 */
53
class HTMLframesConverter extends Converter
54
{
55
    /**
56
     * This converter knows about the new root tree processing
57
     * In order to fix PEAR Bug #6389
58
     * @var boolean
59
     */
60
    var $processSpecialRoots = true;
61
    /**
62
     * Smarty Converter wants elements sorted by type as well as alphabetically
63
     * @see Converter::$sort_page_contents_by_type
64
     * @var boolean
65
     */
66
    var $sort_page_contents_by_type = true;
67
    /** @var string */
68
    var $outputformat = 'HTML';
69
    /** @var string */
70
    var $name = 'frames';
71
    /**
72
     * indexes of elements by package that need to be generated
73
     * @var array
74
     */
75
    var $leftindex = array('classes' => true, 'pages' => true, 'functions' => true, 'defines' => false, 'globals' => false);
76
 
77
    /**
78
     * output directory for the current procedural page being processed
79
     * @var string
80
     */
81
    var $page_dir;
82
 
83
    /**
84
     * target directory passed on the command-line.
85
     * {@link $targetDir} is malleable, always adding package/ and package/subpackage/ subdirectories onto it.
86
     * @var string
87
     */
88
    var $base_dir;
89
 
90
    /**
91
     * output directory for the current class being processed
92
     * @var string
93
     */
94
    var $class_dir;
95
 
96
    /**
97
     * array of converted package page names.
98
     * Used to link to the package page in the left index
99
     * @var array Format: array(package => 1)
100
     */
101
    var $package_pages = array();
102
 
103
    /**
104
     * controls formatting of parser informative output
105
     *
106
     * Converter prints:
107
     * "Converting /path/to/file.php... Procedural Page Elements... Classes..."
108
     * Since HTMLdefaultConverter outputs files while converting, it needs to send a \n to start a new line.  However, if there
109
     * is more than one class, output is messy, with multiple \n's just between class file output.  This variable prevents that
110
     * and is purely cosmetic
111
     * @var boolean
112
     */
113
    var $juststarted = false;
114
 
115
    /**
116
     * contains all of the template procedural page element loop data needed for the current template
117
     * @var array
118
     */
119
    var $current;
120
 
121
    /**
122
     * contains all of the template class element loop data needed for the current template
123
     * @var array
124
     */
125
    var $currentclass;
126
    var $wrote = false;
127
    var $ric_set = array();
128
 
129
    /**
130
     * sets {@link $base_dir} to $targetDir
131
     * @see Converter()
132
     */
133
    function HTMLframesConverter(&$allp, &$packp, &$classes, &$procpages, $po, $pp, $qm, $targetDir, $templateDir, $title)
134
    {
135
        Converter::Converter($allp, $packp, $classes, $procpages,$po, $pp, $qm, $targetDir, $templateDir, $title);
136
        $this->base_dir = $targetDir;
137
    }
138
 
139
    /**
140
     * @deprecated in favor of PHP 4.3.0+ tokenizer-based source highlighting
141
     */
142
    function unmangle($sourcecode)
143
    {
144
        $sourcecode = str_replace('<code>','<pre>',$sourcecode);
145
        $sourcecode = str_replace('</code>','</pre>',$sourcecode);
146
        $sourcecode = str_replace('<br />',"\n",$sourcecode);
147
        $sourcecode = str_replace('&nbsp;',' ',$sourcecode);
148
        $sourcecode = str_replace('&lt;','<',$sourcecode);
149
        $sourcecode = str_replace('&gt;','>',$sourcecode);
150
        $sourcecode = str_replace('&amp;','&',$sourcecode);
151
        return $sourcecode;
152
    }
153
 
154
    /**
155
     * @param string full path to the source file
156
     * @param string fully highlighted source code
157
     */
158
    function writeSource($path, $value)
159
    {
160
        $templ = &$this->newSmarty();
161
        $pathinfo = $this->proceduralpages->getPathInfo($path, $this);
162
        $templ->assign('source',$value);
163
        $templ->assign('package',$pathinfo['package']);
164
        $templ->assign('subpackage',$pathinfo['subpackage']);
165
        $templ->assign('name',$pathinfo['name']);
166
        $templ->assign('source_loc',$pathinfo['source_loc']);
167
        $templ->assign('docs',$pathinfo['docs']);
168
        $templ->assign("subdir",'../');
169
        $templ->register_outputfilter('HTMLframes_outputfilter');
170
        $this->setTargetDir($this->getFileSourcePath($this->base_dir));
171
        phpDocumentor_out("\n");
172
        $this->setSourcePaths($path);
173
        $this->writefile($this->getFileSourceName($path).'.html',$templ->fetch('filesource.tpl'));
174
    }
175
 
176
    function writeExample($title, $path, $source)
177
    {
178
        $templ = &$this->newSmarty();
179
        $templ->assign('source',$source);
180
        if (empty($title))
181
        {
182
            $title = 'example';
183
            addWarning(PDERROR_EMPTY_EXAMPLE_TITLE, $path, $title);
184
        }
185
        $templ->assign('title',$title);
186
        $templ->assign('file',$path);
187
        $templ->assign("subdir",'../');
188
        $templ->register_outputfilter('HTMLframes_outputfilter');
189
        $this->setTargetDir($this->base_dir . PATH_DELIMITER . '__examplesource');
190
        phpDocumentor_out("\n");
191
        $this->writefile('exsource_'.$path.'.html',$templ->fetch('examplesource.tpl'));
192
    }
193
 
194
    function getExampleLink($path, $title)
195
    {
196
        return $this->returnLink('{$subdir}__examplesource' . PATH_DELIMITER . 'exsource_'.$path.'.html',$title);
197
    }
198
 
199
    function getSourceLink($path)
200
    {
201
        return $this->returnLink('{$subdir}__filesource/' .
202
        $this->getFileSourceName($path).'.html','Source Code for this file');
203
    }
204
 
205
    /**
206
     * Retrieve a Converter-specific anchor to a segment of a source code file
207
     * parsed via a {@tutorial tags.filesource.pkg} tag.
208
     * @param string full path to source file
209
     * @param string name of anchor
210
     * @param string link text, if this is a link
211
     * @param boolean returns either a link or a destination based on this
212
     *                parameter
213
     * @return string link to an anchor, or the anchor
214
     */
215
    function getSourceAnchor($sourcefile,$anchor,$text = '',$link = false)
216
    {
217
        if ($link) {
218
            return $this->returnLink('{$subdir}__filesource/' .
219
                $this->getFileSourceName($sourcefile) . '.html#a' . $anchor, $text);
220
        } else {
221
            return '<a name="a'.$anchor.'"></a>';
222
        }
223
    }
224
 
225
    /**
226
     * Return a line of highlighted source code with formatted line number
227
     *
228
     * If the $path is a full path, then an anchor to the line number will be
229
     * added as well
230
     * @param integer line number
231
     * @param string highlighted source code line
232
     * @param false|string full path to @filesource file this line is a part of,
233
     *        if this is a single line from a complete file.
234
     * @return string formatted source code line with line number
235
     */
236
    function sourceLine($linenumber, $line, $path = false)
237
    {
238
        $extra = '';
239
        if (strlen(str_replace("\n", '', $line)) == 0) {
240
            $extra = '&nbsp;';
241
        }
242
        if ($path)
243
        {
244
            return '<li><div class="src-line">' . $this->getSourceAnchor($path, $linenumber) .
245
                   str_replace("\n",'',$line) . $extra .
246
                   "</div></li>\n";
247
        } else
248
        {
249
            return '<li><div class="src-line">' . str_replace("\n",'',$line) .
250
                "$extra</div></li>\n";
251
        }
252
    }
253
 
254
    /**
255
     * Used to convert the <<code>> tag in a docblock
256
     * @param string
257
     * @param boolean
258
     * @return string
259
     */
260
    function ProgramExample($example, $tutorial = false, $inlinesourceparse = null/*false*/,
261
                            $class = null/*false*/, $linenum = null/*false*/, $filesourcepath = null/*false*/)
262
    {
263
        return '<div class="src-code"><ol>' . parent::ProgramExample($example, $tutorial, $inlinesourceparse, $class, $linenum, $filesourcepath)
264
               .'</ol></div>';
265
    }
266
 
267
    /**
268
     * @param string
269
     */
270
    function TutorialExample($example)
271
    {
272
        $trans = $this->template_options['desctranslate'];
273
        $this->template_options['desctranslate'] = array();
274
        $example = '<ol>' . parent::TutorialExample($example)
275
               .'</ol>';
276
        $this->template_options['desctranslate'] = $trans;
277
        if (!isset($this->template_options['desctranslate'])) return $example;
278
        if (!isset($this->template_options['desctranslate']['code'])) return $example;
279
        $example = $this->template_options['desctranslate']['code'] . $example;
280
        if (!isset($this->template_options['desctranslate']['/code'])) return $example;
281
        return $example . $this->template_options['desctranslate']['/code'];
282
    }
283
 
284
    function getCurrentPageLink()
285
    {
286
        return $this->curname . '.html';
287
    }
288
 
289
    /**
290
     * Uses htmlspecialchars() on the input
291
     */
292
    function postProcess($text)
293
    {
294
        if ($this->highlightingSource) {
295
            return str_replace(array(' ',"\t"), array('&nbsp;', '&nbsp;&nbsp;&nbsp;'),
296
                htmlspecialchars($text));
297
        }
298
        return htmlspecialchars($text);
299
    }
300
 
301
    /**
302
     * Use the template tutorial_toc.tpl to generate a table of contents for HTML
303
     * @return string table of contents formatted for use in the current output format
304
     * @param array format: array(array('tagname' => section, 'link' => returnsee link, 'id' => anchor name, 'title' => from title tag),...)
305
     */
306
    function formatTutorialTOC($toc)
307
    {
308
        $template = &$this->newSmarty();
309
        $template->assign('toc',$toc);
310
        return $template->fetch('tutorial_toc.tpl');
311
    }
312
 
313
    function &SmartyInit(&$templ)
314
    {
315
        if (!isset($this->package_index))
316
        foreach($this->all_packages as $key => $val)
317
        {
318
            if (isset($this->pkg_elements[$key]))
319
            {
320
                if (!isset($start)) $start = $key;
321
                $this->package_index[] = array('link' => "li_$key.html", 'title' => $key);
322
            }
323
        }
324
        $templ->assign("packageindex",$this->package_index);
325
        $templ->assign("subdir",'');
326
        return $templ;
327
    }
328
 
329
    /**
330
     * Writes out the template file of {@link $class_data} and unsets the template to save memory
331
     * @see registerCurrentClass()
332
     * @see parent::endClass()
333
     */
334
    function endClass()
335
    {
336
        $a = '../';
337
        if (!empty($this->subpackage)) $a .= '../';
338
        if ($this->juststarted)
339
        {
340
            $this->juststarted = false;
341
            phpDocumentor_out("\n");
342
            flush();
343
        }
344
        $this->setTargetDir($this->base_dir . PATH_DELIMITER . $this->class_dir);
345
        $this->class_data->assign("subdir",$a);
346
        $this->class_data->register_outputfilter('HTMLframes_outputfilter');
347
        $this->writefile($this->class . '.html',$this->class_data->fetch('class.tpl'));
348
        unset($this->class_data);
349
    }
350
 
351
    /**
352
     * Writes out the template file of {@link $page_data} and unsets the template to save memory
353
     * @see registerCurrent()
354
     * @see parent::endPage()
355
     */
356
    function endPage()
357
    {
358
        $this->package = $this->curpage->package;
359
        $this->subpackage = $this->curpage->subpackage;
360
        $a = '../';
361
        if (!empty($this->subpackage)) $a .= '../';
362
        $this->setTargetDir($this->base_dir . PATH_DELIMITER . $this->page_dir);
363
        $this->page_data->assign("package",$this->package);
364
        $this->page_data->assign("subdir",$a);
365
        $this->page_data->register_outputfilter('HTMLframes_outputfilter');
366
        $this->writefile($this->page . '.html',$this->page_data->fetch('page.tpl'));
367
        unset($this->page_data);
368
    }
369
 
370
    /**
371
     * @param string
372
     * @param string
373
     * @return string &lt;a href="'.$link.'">'.$text.'</a&gt;
374
     */
375
    function returnLink($link,$text)
376
    {
377
        return '<a href="'.$link.'">'.$text.'</a>';
378
    }
379
 
380
    function makeLeft()
381
    {
382
        foreach($this->page_elements as $package => $o1)
383
        {
384
            foreach($o1 as $subpackage => $links)
385
            {
386
                for($i=0;$i<count($links);$i++)
387
                {
388
                    $left[$package][$subpackage]['files'][] =
389
                        array("link" => $this->getId($links[$i]), "title" => $links[$i]->name);
390
                }
391
            }
392
        }
393
        $interfaces = $classes = false;
394
        foreach($this->class_elements as $package => $o1)
395
        {
396
            foreach($o1 as $subpackage => $links)
397
            {
398
                for($i=0;$i<count($links);$i++)
399
                {
400
                    $class = $this->classes->getClassByPackage($links[$i]->name, $links[$i]->package);
401
                    $isinterface = $isclass = false;
402
                    if ($class->isInterface()) {
403
                        $isinterface = true;
404
                        $interfaces = true;
405
                    } else {
406
                        $isclass = true;
407
                        $classes = true;
408
                    }
409
                    if ($class && isset($class->docblock) && $class->docblock->hasaccess) {
410
                        $left[$package][$subpackage]['classes'][] =
411
                            array("link" => $this->getId($links[$i]),
412
                                  "title" => $links[$i]->name,
413
                                  'is_interface' => $isinterface,
414
                                  'is_class' => $isclass,
415
                                  "access" => $class->docblock->tags['access'][0]->value,
416
                                  "abstract" => isset ($class->docblock->tags['abstract'][0]));
417
                    } else {
418
                        $left[$package][$subpackage]['classes'][] =
419
                            array("link" => $this->getId($links[$i]),
420
                                  "title" => $links[$i]->name,
421
                                  'is_interface' => $isinterface,
422
                                  'is_class' => $isclass,
423
                                  "access" => 'public',
424
                                  "abstract" => isset ($class->docblock->tags['abstract'][0]));
425
                    }
426
                }
427
            }
428
        }
429
        foreach($this->function_elements as $package => $o1)
430
        {
431
            foreach($o1 as $subpackage => $links)
432
            {
433
                for($i=0;$i<count($links);$i++)
434
                {
435
                    $left[$package][$subpackage]['functions'][] =
436
                        array("link" => $this->getId($links[$i]), "title" => $links[$i]->name);
437
                }
438
            }
439
        }
440
        $ret = array();
441
        foreach($left as $package => $r)
442
        {
443
            $pd = 'blank';
444
            if (isset($this->package_pages[$package])) $pd = $package.'/package_'.$package.'.html';
445
            if (!isset($r['']))
446
            {
447
                $pt = false;
448
                $ptnoa = false;
449
                $ptt = $package;
450
                if ($t = $this->hasTutorial('pkg',$package,$package,''))
451
                {
452
                    $pt = $t->getLink($this);
453
                    $ptnoa = $this->getId($t->getLink($this,true));
454
                    $ptt = $t->getTitle($this);
455
                }
456
                $tutes = array();
457
                foreach($this->tutorial_tree as $root => $tr)
458
                {
459
                    if ($tr['tutorial']->package == $package && $tr['tutorial']->subpackage == '') {
460
                        $tutes[$tr['tutorial']->tutorial_type][] =
461
                            $this->getTutorialTree($tr['tutorial']);
462
                    }
463
                }
464
                if (isset($this->childless_tutorials[$package][$subpackage]))
465
                {
466
                    foreach($this->childless_tutorials[$package][$subpackage] as $ext => $other)
467
                    {
468
                        foreach($other as $tutorial)
469
                        {
470
                            $tutes[$tutorial->tutorial_type][] = $this->getTutorialTree($tutorial);
471
                        }
472
                    }
473
                }
474
                $ret[$package][] =
475
                    array(
476
                        'package' => $package,
477
                        'subpackage' => '',
478
                        'packagedoc' => $pd,
479
                        'packagetutorial' => $pt,
480
                        'packagetutorialnoa' => $ptnoa,
481
                        'packagetutorialtitle' => $ptt,
482
                        'files' => array(),
483
                        'functions' => array(),
484
                        'classes' => array(),
485
                        'tutorials' => $tutes,
486
                        );
487
            }
488
            foreach($r as $subpackage => $info)
489
            {
490
                $my = array();
491
                $my['package'] = $package;
492
                if (isset($this->package_pages[$package]))
493
                $my['packagedoc'] = $pd;
494
                else
495
                $my['packagedoc'] = 'blank';
496
                $my['subpackage'] = $subpackage;
497
                if (empty($subpackage))
498
                {
499
                    if ($t = $this->hasTutorial('pkg',$package,$package,$subpackage))
500
                    {
501
                        $my['packagetutorial'] = $t->getLink($this);
502
                        $my['packagetutorialnoa'] = $this->getId($t->getLink($this,true));
503
                        $my['packagetutorialtitle'] = $t->getTitle($this);
504
                    } else
505
                    {
506
                        $my['packagetutorial'] = '<a href="blank.html">No Package-Level Tutorial</a>';
507
                        $my['packagetutorialnoa'] = 'blank.html';
508
                        $my['packagetutorialtitle'] = $package;
509
                    }
510
                } else
511
                {
512
                    if ($t = $this->hasTutorial('pkg',$subpackage,$package,$subpackage))
513
                    {
514
                        $my['subpackagetutorial'] = $this->returnSee($this->getTutorialLink($t));
515
                        $my['subpackagetutorialnoa'] = $this->getId($t->getLink($this,true));
516
                        $my['subpackagetutorialtitle'] = $t->getTitle($this);
517
                    } else
518
                    {
519
                        $my['subpackagetutorial'] = false;
520
                        $my['subpackagetutorialnoa'] = false;
521
                        $my['subpackagetutorialtitle'] = $subpackage;
522
                    }
523
                }
524
                $tutes = array();
525
                foreach($this->tutorial_tree as $root => $tr)
526
                {
527
                    if ($tr['tutorial']->package == $package && $tr['tutorial']->subpackage == $subpackage)
528
                    {
529
                        $tutes[$tr['tutorial']->tutorial_type][] = $this->getTutorialTree($tr['tutorial']);
530
                    }
531
                }
532
                $my['tutorials'] = $tutes;
533
                $my['files'] = $my['classes'] = $my['functions'] = array();
534
                if (isset($info['files']))
535
                $my['files'] = $info['files'];
536
                if (isset($info['classes']))
537
                $my['classes'] = $info['classes'];
538
                $my['hasclasses'] = $classes;
539
                $my['hasinterfaces'] = $interfaces;
540
                if (isset($info['functions']))
541
                $my['functions'] = $info['functions'];
542
                $ret[$package][] = $my;
543
            }
544
        }
545
        return $ret;
546
    }
547
 
548
    function getTutorialTree($tutorial,$k = false)
549
    {
550
        $ret = '';
551
        if (is_object($tutorial)) $tree = parent::getTutorialTree($tutorial); else $tree = $tutorial;
552
//        debug($this->vardump_tree($tree));exit;
553
        if (!$tree)
554
        {
555
            $template = &$this->newSmarty();
556
            $template->assign('subtree',false);
557
            $template->assign('name',str_replace('.','',$tutorial->name));
558
            $template->assign('parent',false);
559
            $template->assign('haskids',false);
560
            $template->assign('kids','');
561
            $link = new tutorialLink;
562
            $t = $tutorial;
563
            $link->addLink('',$t->path,$t->name,$t->package,$t->subpackage,$t->getTitle($this));
564
            $main = array('link' => $this->getId($link), 'title' => $link->title);
565
            $template->assign('main',$main);
566
            return $template->fetch('tutorial_tree.tpl');
567
        }
568
        if (isset($tree['kids']))
569
        {
570
            foreach($tree['kids'] as $subtree)
571
            {
572
                $ret .= $this->getTutorialTree($subtree, true);
573
            }
574
        }
575
        $template = &$this->newSmarty();
576
        $template->assign('subtree',$k);
577
        $template->assign('name',str_replace('.','',$tree['tutorial']->name));
578
        $template->assign('parent',($k ? str_replace('.','',$tree['tutorial']->parent->name) : false));
579
        $template->assign('haskids',strlen($ret));
580
        $template->assign('kids',$ret);
581
        $link = new tutorialLink;
582
        $t = $tree['tutorial'];
583
        $link->addLink('',$t->path,$t->name,$t->package,$t->subpackage,$t->getTitle($this));
584
        $main = array('link' => $this->getId($link), 'title' => $link->title);
585
        $template->assign('main',$main);
586
        $ret = $template->fetch('tutorial_tree.tpl');
587
				return $ret;
588
    }
589
 
590
    /**
591
     * HTMLdefaultConverter chooses to format both package indexes and the complete index here
592
     *
593
     * This function formats output for the elementindex.html and pkgelementindex.html template files.  It then
594
     * writes them to the target directory
595
     * @see generateElementIndex(), generatePkgElementIndex()
596
     */
597
    function formatPkgIndex()
598
    {
599
        list($package_indexes,$packages,$mletters) = $this->generatePkgElementIndexes();
600
        for($i=0;$i<count($package_indexes);$i++)
601
        {
602
            $template = &$this->newSmarty();
603
            $this->package = $package_indexes[$i]['package'];
604
            $this->subpackage = '';
605
            $template->assign("index",$package_indexes[$i]['pindex']);
606
            $template->assign("package",$package_indexes[$i]['package']);
607
            $template->assign("letters",$mletters[$package_indexes[$i]['package']]);
608
            $template->register_outputfilter('HTMLframes_outputfilter');
609
            $this->setTargetDir($this->base_dir);
610
            $this->writefile('elementindex_'.$package_indexes[$i]['package'].'.html',$template->fetch('pkgelementindex.tpl'));
611
        }
612
        phpDocumentor_out("\n");
613
        flush();
614
        }
615
 
616
    /**
617
     * HTMLdefaultConverter uses this function to format template index.html and packages.html
618
     *
619
     * This function generates the package list from {@link $all_packages}, eliminating any
620
     * packages that don't have any entries in their package index (no files at all, due to @ignore
621
     * or other factors).  Then it uses the default package name as the first package index to display.
622
     * It sets the right pane to be either a blank file with instructions on making package-level docs,
623
     * or the package-level docs for the default package.
624
     * @global string Used to set the starting package to display
625
     */
626
    function formatIndex()
627
    {
628
        global $phpDocumentor_DefaultPackageName;
629
        list($elindex,$mletters) = $this->generateElementIndex();
630
        $template = &$this->newSmarty();
631
        $template->assign("index",$elindex);
632
        $template->assign("letters",$mletters);
633
        $template->register_outputfilter('HTMLframes_outputfilter');
634
        phpDocumentor_out("\n");
635
        flush();
636
        $this->setTargetDir($this->base_dir);
637
        $this->writefile('elementindex.html',$template->fetch('elementindex.tpl'));
638
        usort($this->package_index,"HTMLframes_pindexcmp");
639
        $index = &$this->newSmarty();
640
        foreach($this->all_packages as $key => $val)
641
        {
642
            if (isset($this->pkg_elements[$key]))
643
            {
644
                if (!isset($start)) $start = $key;
645
                if (!isset($this->package_pages[$key])) $this->writeNewPPage($key);
646
            }
647
        }
648
        // Created index.html
649
        if (isset($this->pkg_elements[$phpDocumentor_DefaultPackageName])) $start = $phpDocumentor_DefaultPackageName;
650
        $this->package = $start;
651
        $this->subpackage = '';
652
        $index->assign("package_count",count($this->pkg_elements));
653
        if (count($this->ric_set))
654
        $index->assign("package_count",2);
655
        $index->assign("date",date("r",time()));
656
        $index->assign("title",$this->title);
657
        $index->assign("start","li_$start.html");
658
        $index->register_outputfilter('HTMLframes_outputfilter');
659
        if (isset($this->tutorials[$start]['']['pkg'][$start . '.pkg']))
660
        {
661
            $index->assign("blank",$start.'/tutorial_'.$start.'.pkg');
662
        } elseif (isset($this->package_pages[$start]))
663
        {
664
            $index->assign("blank",$start.'/package_'.$start);
665
        }
666
        else
667
        {
668
            $index->assign("blank","blank");
669
            $blank = &$this->newSmarty();
670
            $blank->assign('package',$this->package);
671
            $this->setTargetDir($this->base_dir);
672
            $this->writefile("blank.html",$blank->fetch('blank.tpl'));
673
        }
674
        phpDocumentor_out("\n");
675
        flush();
676
        $this->setTargetDir($this->base_dir);
677
        $this->writefile("index.html",$index->fetch('index.tpl'));
678
 
679
        // Create package index
680
        $package = &$this->newSmarty();
681
        $package->assign('ric',array());
682
        if (isset($this->ric_set))
683
        {
684
            foreach($this->ric_set as $name => $u)
685
            {
686
                $package->append('ric',array('file' => 'ric_'.$name.'.html','name' => $name));
687
            }
688
        }
689
        $package->assign("packages",$this->package_index);
690
        $package->register_outputfilter('HTMLframes_outputfilter');
691
        $this->writefile("packages.html",$package->fetch('top_frame.tpl'));
692
        unset($index);
693
    }
694
 
695
    function writeNewPPage($key)
696
    {
697
        return;
698
        $template = &$this->newSmarty();
699
        $this->package = $key;
700
        $this->subpackage = '';
701
        $template->assign("date",date("r",time()));
702
        $template->assign("title",$this->title);
703
        $template->assign("package",$key);
704
        $template->register_outputfilter('HTMLframes_outputfilter');
705
        phpDocumentor_out("\n");
706
        flush();
707
        $this->setTargetDir($this->base_dir);
708
 
709
        $this->writefile("li_$key.html",$template->fetch('index.tpl'));
710
        unset($template);
711
    }
712
 
713
    /**
714
     * Generate indexes for li_package.html and classtree output files
715
     *
716
     * This function generates the li_package.html files from the template file left.html.  It does this by
717
     * iterating through each of the $page_elements, $class_elements and  $function_elements arrays to retrieve
718
     * the pre-sorted {@link abstractLink} descendants needed for index generation.  Conversion of these links to
719
     * text is done by {@link returnSee()}.  The {@link $local} parameter is set to false to ensure that paths are correct.
720
     *
721
     * Then it uses {@link generateFormattedClassTrees()} to create class trees from the template file classtrees.html.  Output
722
     * filename is classtrees_packagename.html.  This function also unsets {@link $elements} and {@link $pkg_elements} to free
723
     * up the considerable memory these two class vars use
724
     * @see $page_elements, $class_elements, $function_elements
725
     */
726
    function formatLeftIndex()
727
    {
728
        phpDocumentor_out("\n");
729
        flush();
730
        $this->setTargetDir($this->base_dir);
731
        if (0)//!isset($this->left))
732
        {
733
            debug("Nothing parsed, check the command-line");
734
            die();
735
        }
736
        $x = $this->makeLeft();
737
        foreach($this->all_packages as $package => $rest)
738
        {
739
            if (!isset($this->pkg_elements[$package])) continue;
740
            $template = &$this->newSmarty();
741
            $template->assign("info",$x[$package]);
742
            $template->assign('package',$package);
743
            $template->assign("hastutorials",isset($this->tutorials[$package]));
744
            $template->assign('hastodos',count($this->todoList));
745
            $template->assign('todolink','todolist.html');
746
            $template->assign("classtreepage","classtrees_$package");
747
            $template->assign("elementindex","elementindex_$package");
748
            $template->register_outputfilter('HTMLframes_outputfilter');
749
            if (isset($this->package_pages[$package]))
750
            {
751
                $template->assign("packagedoc",$package.'/package_' . $package . '.html');
752
            } else
753
            {
754
                $template->assign("packagedoc",false);
755
            }
756
            $this->writefile("li_$package.html",$template->fetch('left_frame.tpl'));
757
 
758
            // Create class tree page
759
            $template = &$this->newSmarty();
760
            $template->assign("classtrees",$this->generateFormattedClassTrees($package));
761
            $template->assign("interfaces",$this->generateFormattedInterfaceTrees($package));
762
            $template->assign("package",$package);
763
            $template->register_outputfilter('HTMLframes_outputfilter');
764
            $this->writefile("classtrees_$package.html",$template->fetch('classtrees.tpl'));
765
            phpDocumentor_out("\n");
766
            flush();
767
        }
768
        // free up considerable memory
769
        unset($this->elements);
770
        unset($this->pkg_elements);
771
    }
772
 
773
    /**
774
     * This function takes an {@link abstractLink} descendant and returns an html link
775
     *
776
     * @param abstractLink a descendant of abstractlink should be passed, and never text
777
     * @param string text to display in the link
778
     * @param boolean this parameter is not used, and is deprecated
779
     * @param boolean determines whether the returned text is enclosed in an <a> tag
780
     */
781
    function returnSee(&$element, $eltext = false, $with_a = true)
782
    {
783
        if (!is_object($element) || !$element) return false;
784
        if (!$with_a) return $this->getId($element, false);
785
        if (!$eltext)
786
        {
787
            $eltext = '';
788
            switch($element->type)
789
            {
790
                case 'tutorial' :
791
                $eltext = strip_tags($element->title);
792
                break;
793
                case 'method' :
794
                case 'var' :
795
                case 'const' :
796
                $eltext .= $element->class.'::';
797
                case 'page' :
798
                case 'define' :
799
                case 'class' :
800
                case 'function' :
801
                case 'global' :
802
                default :
803
                $eltext .= $element->name;
804
                if ($element->type == 'function' || $element->type == 'method') $eltext .= '()';
805
                break;
806
            }
807
        }
808
        return '<a href="'.$this->getId($element).'">'.$eltext.'</a>';
809
    }
810
 
811
    function getId($element, $fullpath = true)
812
    {
813
        if (phpDocumentor_get_class($element) == 'parserdata')
814
        {
815
            $element = $this->addLink($element->parent);
816
            $elp = $element->parent;
817
        } elseif (is_a($element, 'parserbase'))
818
        {
819
            $elp = $element;
820
            $element = $this->addLink($element);
821
        }
822
        $c = '';
823
        if (!empty($element->subpackage))
824
        {
825
            $c = '/'.$element->subpackage;
826
        }
827
        $b = '{$subdir}';
828
        switch ($element->type)
829
        {
830
            case 'page' :
831
            if ($fullpath)
832
            return $b.$element->package.$c.'/'.$element->fileAlias.'.html';
833
            return 'top';
834
            break;
835
            case 'define' :
836
            case 'global' :
837
            case 'function' :
838
            if ($fullpath)
839
            return $b.$element->package.$c.'/'.$element->fileAlias.'.html#'.$element->type.$element->name;
840
            return $element->type.$element->name;
841
            break;
842
            case 'class' :
843
            if ($fullpath)
844
            return $b.$element->package.$c.'/'.$element->name.'.html';
845
            return 'top';
846
            break;
847
            case 'method' :
848
            case 'var' :
849
            case 'const' :
850
            if ($fullpath)
851
            return $b.$element->package.$c.'/'.$element->class.'.html#'.$element->type.$element->name;
852
            return $element->type.$element->name;
853
            break;
854
            case 'tutorial' :
855
            $d = '';
856
            if ($element->section)
857
            {
858
                $d = '#'.$element->section;
859
            }
860
            return $b.$element->package.$c.'/tutorial_'.$element->name.'.html'.$d;
861
        }
862
    }
863
 
864
    /**
865
     * Convert README/INSTALL/CHANGELOG file contents to output format
866
     * @param README|INSTALL|CHANGELOG
867
     * @param string contents of the file
868
     */
869
    function Convert_RIC($name, $contents)
870
    {
871
        $template = &$this->newSmarty();
872
        $template->assign('contents',$contents);
873
        $template->assign('name',$name);
874
        $this->setTargetDir($this->base_dir);
875
        $this->writefile('ric_'.$name . '.html',$template->fetch('ric.tpl'));
876
        $this->ric_set[$name] = true;
877
    }
878
 
879
    function ConvertTodoList()
880
    {
881
        $todolist = array();
882
        foreach($this->todoList as $package => $alltodos)
883
        {
884
            foreach($alltodos as $todos)
885
            {
886
                $converted = array();
887
                $converted['link'] = $this->returnSee($todos[0]);
888
                if (!is_array($todos[1]))
889
                {
890
                    $converted['todos'][] = $todos[1]->Convert($this);
891
                } else
892
                {
893
                    foreach($todos[1] as $todo)
894
                    {
895
                        $converted['todos'][] = $todo->Convert($this);
896
                    }
897
                }
898
                $todolist[$package][] = $converted;
899
            }
900
        }
901
        $templ = &$this->newSmarty();
902
        $templ->assign('todos',$todolist);
903
        $templ->register_outputfilter('HTMLframes_outputfilter');
904
        $this->setTargetDir($this->base_dir);
905
        $this->writefile('todolist.html',$templ->fetch('todolist.tpl'));
906
    }
907
 
908
    /**
909
     * Create errors.html template file output
910
     *
911
     * This method takes all parsing errors and warnings and spits them out ordered by file and line number.
912
     * @global ErrorTracker We'll be using it's output facility
913
     */
914
    function ConvertErrorLog()
915
    {
916
        global $phpDocumentor_errors;
917
        $allfiles = array();
918
        $files = array();
919
        $warnings = $phpDocumentor_errors->returnWarnings();
920
        $errors = $phpDocumentor_errors->returnErrors();
921
        $template = &$this->newSmarty();
922
        foreach($warnings as $warning)
923
        {
924
            $file = '##none';
925
            $linenum = 'Warning';
926
            if ($warning->file)
927
            {
928
                $file = $warning->file;
929
                $allfiles[$file] = 1;
930
                $linenum .= ' on line '.$warning->linenum;
931
            }
932
            $files[$file]['warnings'][] = array('name' => $linenum, 'listing' => $warning->data);
933
        }
934
        foreach($errors as $error)
935
        {
936
            $file = '##none';
937
            $linenum = 'Error';
938
            if ($error->file)
939
            {
940
                $file = $error->file;
941
                $allfiles[$file] = 1;
942
                $linenum .= ' on line '.$error->linenum;
943
            }
944
            $files[$file]['errors'][] = array('name' => $linenum, 'listing' => $error->data);
945
        }
946
        $i=1;
947
        $af = array();
948
        foreach($allfiles as $file => $num)
949
        {
950
            $af[$i++] = $file;
951
        }
952
        $allfiles = $af;
953
        usort($allfiles,'strnatcasecmp');
954
        $allfiles[0] = "Post-parsing";
955
        foreach($allfiles as $i => $a)
956
        {
957
            $allfiles[$i] = array('file' => $a);
958
        }
959
        $out = array();
960
        foreach($files as $file => $data)
961
        {
962
            if ($file == '##none') $file = 'Post-parsing';
963
            $out[$file] = $data;
964
        }
965
        $template->assign("files",$allfiles);
966
        $template->assign("all",$out);
967
        $template->assign("title","phpDocumentor Parser Errors and Warnings");
968
        $this->setTargetDir($this->base_dir);
969
        $this->writefile("errors.html",$template->fetch('errors.tpl'));
970
        unset($template);
971
        phpDocumentor_out("\n\nTo view errors and warnings, look at ".$this->base_dir. PATH_DELIMITER . "errors.html\n");
972
        flush();
973
    }
974
 
975
    function getTutorialId($package,$subpackage,$tutorial,$id)
976
    {
977
        return $id;
978
    }
979
 
980
    function getCData($value)
981
    {
982
        return '<pre>'.htmlentities($value).'</pre>';
983
    }
984
 
985
    /**
986
     * Converts package page and sets its package as used in {@link $package_pages}
987
     * @param parserPackagePage
988
     */
989
    function convertPackagepage(&$element)
990
    {
991
        phpDocumentor_out("\n");
992
        flush();
993
        $this->package = $element->package;
994
        $this->subpackage = '';
995
        $contents = $element->Convert($this);
996
        $this->package_pages[$element->package] = str_replace('{$subdir}','../',$contents);
997
        phpDocumentor_out("\n");
998
        flush();
999
        $this->setTargetDir($this->base_dir . PATH_DELIMITER . $element->package);
1000
        $this->writeFile('package_'.$element->package.'.html',str_replace('{$subdir}','../',$contents));
1001
    }
1002
 
1003
    /**
1004
     * @param parserTutorial
1005
     */
1006
    function convertTutorial(&$element)
1007
    {
1008
        phpDocumentor_out("\n");
1009
        flush();
1010
        $template = &parent::convertTutorial($element);
1011
        $a = '../';
1012
        if ($element->subpackage) $a .= '../';
1013
        $template->assign('subdir',$a);
1014
        $template->register_outputfilter('HTMLframes_outputfilter');
1015
        $contents = $template->fetch('tutorial.tpl');
1016
        $a = '';
1017
        if ($element->subpackage) $a = PATH_DELIMITER . $element->subpackage;
1018
        phpDocumentor_out("\n");
1019
        flush();
1020
        $this->setTargetDir($this->base_dir . PATH_DELIMITER . $element->package . $a);
1021
        $this->writeFile('tutorial_'.$element->name.'.html',$contents);
1022
    }
1023
 
1024
    /**
1025
     * Converts class for template output
1026
     * @see prepareDocBlock(), generateChildClassList(), generateFormattedClassTree(), getFormattedConflicts()
1027
     * @see getFormattedInheritedMethods(), getFormattedInheritedVars()
1028
     * @param parserClass
1029
     */
1030
    function convertClass(&$element)
1031
    {
1032
        parent::convertClass($element);
1033
        $this->class_dir = $element->docblock->package;
1034
        if (!empty($element->docblock->subpackage)) $this->class_dir .= PATH_DELIMITER . $element->docblock->subpackage;
1035
        $a = '../';
1036
        if ($element->docblock->subpackage != '') $a = "../$a";
1037
 
1038
        $this->class_data->assign('subdir',$a);
1039
        $this->class_data->assign("title","Docs For Class " . $element->getName());
1040
        $this->class_data->assign("page",$element->getName() . '.html');
1041
    }
1042
 
1043
    /**
1044
     * Converts class variables for template output
1045
     * @see prepareDocBlock(), getFormattedConflicts()
1046
     * @param parserDefine
1047
     */
1048
    function convertVar(&$element)
1049
    {
1050
        parent::convertVar($element, array('var_dest' => $this->getId($element,false)));
1051
    }
1052
 
1053
    /**
1054
     * Converts class variables for template output
1055
     * @see prepareDocBlock(), getFormattedConflicts()
1056
     * @param parserDefine
1057
     */
1058
    function convertConst(&$element)
1059
    {
1060
        parent::convertConst($element, array('const_dest' => $this->getId($element,false)));
1061
    }
1062
 
1063
    /**
1064
     * Converts class methods for template output
1065
     * @see prepareDocBlock(), getFormattedConflicts()
1066
     * @param parserDefine
1067
     */
1068
    function convertMethod(&$element)
1069
    {
1070
        parent::convertMethod($element, array('method_dest' => $this->getId($element,false)));
1071
    }
1072
 
1073
    /**
1074
     * Converts function for template output
1075
     * @see prepareDocBlock(), parserFunction::getFunctionCall(), getFormattedConflicts()
1076
     * @param parserFunction
1077
     */
1078
    function convertFunction(&$element)
1079
    {
1080
        $funcloc = $this->getId($this->addLink($element));
1081
        parent::convertFunction($element,array('function_dest' => $this->getId($element,false)));
1082
    }
1083
 
1084
    /**
1085
     * Converts include elements for template output
1086
     * @see prepareDocBlock()
1087
     * @param parserInclude
1088
     */
1089
    function convertInclude(&$element)
1090
    {
1091
        parent::convertInclude($element, array('include_file'    => '_'.strtr($element->getValue(),array('"' => '', "'" => '','.' => '_'))));
1092
    }
1093
 
1094
    /**
1095
     * Converts defines for template output
1096
     * @see prepareDocBlock(), getFormattedConflicts()
1097
     * @param parserDefine
1098
     */
1099
    function convertDefine(&$element)
1100
    {
1101
        parent::convertDefine($element, array('define_link' => $this->getId($element,false)));
1102
    }
1103
 
1104
    /**
1105
     * Converts global variables for template output
1106
     * @param parserGlobal
1107
     */
1108
    function convertGlobal(&$element)
1109
    {
1110
        parent::convertGlobal($element, array('global_link' => $this->getId($element,false)));
1111
    }
1112
 
1113
    /**
1114
     * converts procedural pages for template output
1115
     * @see prepareDocBlock(), getClassesOnPage()
1116
     * @param parserData
1117
     */
1118
    function convertPage(&$element)
1119
    {
1120
        parent::convertPage($element);
1121
        $this->juststarted = true;
1122
        $this->page_dir = $element->parent->package;
1123
        if (!empty($element->parent->subpackage)) $this->page_dir .= PATH_DELIMITER . $element->parent->subpackage;
1124
        // registering stuff on the template
1125
        $this->page_data->assign("page",$this->getPageName($element) . '.html');
1126
        $this->page_data->assign("title","Docs for page ".$element->parent->getFile());
1127
    }
1128
 
1129
    function getPageName(&$element)
1130
    {
1131
        if (phpDocumentor_get_class($element) == 'parserpage') return '_'.$element->getName();
1132
        return '_'.$element->parent->getName();
1133
    }
1134
 
1135
    /**
1136
     * returns an array containing the class inheritance tree from the root object to the class
1137
     *
1138
     * @param parserClass    class variable
1139
     * @return array Format: array(root,child,child,child,...,$class)
1140
     * @uses parserClass::getParentClassTree()
1141
     */
1142
 
1143
    function generateFormattedClassTree($class)
1144
    {
1145
        $tree = $class->getParentClassTree($this);
1146
        $out = '';
1147
        if (count($tree) - 1)
1148
        {
1149
            $result = array($class->getName());
1150
            $parent = $tree[$class->getName()];
1151
            $distance[] = '';
1152
            while ($parent)
1153
            {
1154
                $x = $parent;
1155
                if (is_object($parent))
1156
                {
1157
                    $subpackage = $parent->docblock->subpackage;
1158
                    $package = $parent->docblock->package;
1159
                    $x = $parent;
1160
                    $x = $parent->getLink($this);
1161
                    if (!$x) $x = $parent->getName();
1162
                }
1163
                $result[] =
1164
                    $x;
1165
                $distance[] =
1166
                    "\n%s|\n" .
1167
                    "%s--";
1168
                if (is_object($parent))
1169
                $parent = $tree[$parent->getName()];
1170
                elseif (isset($tree[$parent]))
1171
                $parent = $tree[$parent];
1172
            }
1173
            $nbsp = '   ';
1174
            for($i=count($result) - 1;$i>=0;$i--)
1175
            {
1176
                $my_nbsp = '';
1177
                for($j=0;$j<count($result) - $i;$j++) $my_nbsp .= $nbsp;
1178
                $distance[$i] = sprintf($distance[$i],$my_nbsp,$my_nbsp);
1179
            }
1180
            return array('classes'=>array_reverse($result),'distance'=>array_reverse($distance));
1181
        } else
1182
        {
1183
            return array('classes'=>$class->getName(),'distance'=>array(''));
1184
        }
1185
    }
1186
 
1187
    /** @access private */
1188
    function sortVar($a, $b)
1189
    {
1190
        return strnatcasecmp($a->getName(),$b->getName());
1191
    }
1192
 
1193
    /** @access private */
1194
    function sortMethod($a, $b)
1195
    {
1196
        if ($a->isConstructor) return -1;
1197
        if ($b->isConstructor) return 1;
1198
        return strnatcasecmp($a->getName(),$b->getName());
1199
    }
1200
 
1201
    /**
1202
     * returns a template-enabled array of class trees
1203
     *
1204
     * @param    string    $package    package to generate a class tree for
1205
     * @see $roots, HTMLConverter::getRootTree()
1206
     */
1207
    function generateFormattedClassTrees($package)
1208
    {
1209
        if (!isset($this->roots['normal'][$package]) &&
1210
              !isset($this->roots['special'][$package])) {
1211
            return array();
1212
        }
1213
        $trees = array();
1214
        if (isset($this->roots['normal'][$package])) {
1215
            $roots = $this->roots['normal'][$package];
1216
            for($i=0;$i<count($roots);$i++)
1217
            {
1218
                $root = $this->classes->getClassByPackage($roots[$i], $package);
1219
                if ($root && $root->isInterface()) {
1220
                    continue;
1221
                }
1222
                $trees[] = array('class' => $roots[$i],'class_tree' => "<ul>\n".$this->getRootTree($this->getSortedClassTreeFromClass($roots[$i],$package,''),$package)."</ul>\n");
1223
            }
1224
        }
1225
        if (isset($this->roots['special'][$package])) {
1226
            $roots = $this->roots['special'][$package];
1227
            foreach ($roots as $parent => $classes) {
1228
                $thistree = '';
1229
                foreach ($classes as $classinfo) {
1230
                    $root = $this->classes->getClassByPackage($classinfo, $package);
1231
                    if ($root && $root->isInterface()) {
1232
                        continue;
1233
                    }
1234
                    $thistree .=
1235
                        $this->getRootTree(
1236
                            $this->getSortedClassTreeFromClass(
1237
                                $classinfo,
1238
                                $package,
1239
                                ''),
1240
                            $package,
1241
                            true);
1242
                }
1243
                if (!$thistree) {
1244
                    continue;
1245
                }
1246
                $trees[] = array(
1247
                    'class' => $parent,
1248
                    'class_tree' => "<ul>\n" . $thistree . "</ul>\n"
1249
                );
1250
            }
1251
        }
1252
        return $trees;
1253
    }
1254
 
1255
    /**
1256
     * returns a template-enabled array of interface inheritance trees
1257
     *
1258
     * @param    string    $package    package to generate a class tree for
1259
     * @see $roots, HTMLConverter::getRootTree()
1260
     */
1261
    function generateFormattedInterfaceTrees($package)
1262
    {
1263
        if (!isset($this->roots['normal'][$package]) &&
1264
              !isset($this->roots['special'][$package])) {
1265
            return array();
1266
        }
1267
        $trees = array();
1268
        if (isset($this->roots['normal'][$package])) {
1269
            $roots = $this->roots['normal'][$package];
1270
            for($i=0;$i<count($roots);$i++)
1271
            {
1272
                $root = $this->classes->getClassByPackage($roots[$i], $package);
1273
                if ($root && !$root->isInterface()) {
1274
                    continue;
1275
                }
1276
                $trees[] = array('class' => $roots[$i],'class_tree' => "<ul>\n".$this->getRootTree($this->getSortedClassTreeFromClass($roots[$i],$package,''),$package)."</ul>\n");
1277
            }
1278
        }
1279
        if (isset($this->roots['special'][$package])) {
1280
            $roots = $this->roots['special'][$package];
1281
            foreach ($roots as $parent => $classes) {
1282
                $thistree = '';
1283
                foreach ($classes as $classinfo) {
1284
                    $root = $this->classes->getClassByPackage($classinfo, $package);
1285
                    if ($root && !$root->isInterface()) {
1286
                        continue;
1287
                    }
1288
                    $thistree .=
1289
                        $this->getRootTree(
1290
                            $this->getSortedClassTreeFromClass(
1291
                                $classinfo,
1292
                                $package,
1293
                                ''),
1294
                            $package,
1295
                            true);
1296
                }
1297
                if (!$thistree) {
1298
                    continue;
1299
                }
1300
                $trees[] = array(
1301
                    'class' => $parent,
1302
                    'class_tree' => "<ul>\n" . $thistree . "</ul>\n"
1303
                );
1304
            }
1305
        }
1306
        return $trees;
1307
    }
1308
 
1309
    /**
1310
     * return formatted class tree for the Class Trees page
1311
     *
1312
     * @param array $tree output from {@link getSortedClassTreeFromClass()}
1313
     * @param string $package  package
1314
     * @param boolean $nounknownparent if true, an object's parent will not be checked
1315
     * @see Classes::$definitechild, generateFormattedClassTrees()
1316
     * @return string
1317
     */
1318
    function getRootTree($tree, $package, $noparent = false)
1319
    {
1320
        if (!$tree) return '';
1321
        $my_tree = '';
1322
        $cur = '#root';
1323
        $lastcur = array(false);
1324
        $kids = array();
1325
        $dopar = false;
1326
        if (!$noparent && $tree[$cur]['parent'])
1327
        {
1328
            $dopar = true;
1329
            if (!is_object($tree[$cur]['parent']))
1330
            {
1331
//                debug("parent ".$tree[$cur]['parent']." not found");
1332
                $my_tree .= '<li>' . $tree[$cur]['parent'] .'<ul>';
1333
            }
1334
            else
1335
            {
1336
//                        debug("parent ".$this->returnSee($tree[$cur]['parent'])." in other package");
1337
                $root = $this->classes->getClassByPackage($tree[$cur]['parent']->name,
1338
                    $package);
1339
                $my_tree .= '<li>' . $this->returnSee($tree[$cur]['parent']);
1340
                if ($tree[$cur]['parent']->package != $package) $my_tree .= ' <b>(Different package)</b><ul>';
1341
            }
1342
        }
1343
        do
1344
        {
1345
//            fancy_debug($cur,$lastcur,$kids);
1346
            if (count($tree[$cur]['children']))
1347
            {
1348
//                debug("$cur has children");
1349
                if (!isset($kids[$cur]))
1350
                {
1351
//                    debug("set $cur kids");
1352
                    $kids[$cur] = 1;
1353
                    $root = $this->classes->getClassByPackage(
1354
                        $tree[$cur]['link']->name,
1355
                        $tree[$cur]['link']->package);
1356
                    if ($implements = $root->getImplements()) {
1357
                        $my_tree .= '<li>'.$this->returnSee($tree[$cur]['link']) .
1358
                            ' (implements ';
1359
                        foreach ($implements as $i => $interface) {
1360
                            if ($i && $i != count($implements) - 1) $my_tree .= ', ';
1361
                            if ($link = $this->getLink('object ' .  $interface)) {
1362
                                $my_tree .= $this->returnSee($link);
1363
                            } else {
1364
                                $my_tree .= $interface;
1365
                            }
1366
                        }
1367
                        $my_tree .= ')';
1368
                    } else {
1369
                        $my_tree .= '<li>'.$this->returnSee($tree[$cur]['link']);
1370
                    }
1371
                    $my_tree .= '<ul>'."\n";
1372
                }
1373
                array_push($lastcur,$cur);
1374
                list(,$cur) = each($tree[$cur]['children']);
1375
//                var_dump('listed',$cur);
1376
                if ($cur)
1377
                {
1378
                    $cur = $cur['package'] . '#' . $cur['class'];
1379
//                    debug("set cur to child $cur");
1380
//                    $my_tree .= '<li>'.$this->returnSee($tree[$cur]['link']);
1381
                    continue;
1382
                } else
1383
                {
1384
//                    debug("end of children for $cur");
1385
                    $cur = array_pop($lastcur);
1386
                    $cur = array_pop($lastcur);
1387
                    $my_tree .= '</ul></li>'."\n";
1388
                    if ($dopar && ($cur == '#root' || !$cur)) $my_tree .= '</ul></li>';
1389
                }
1390
            } else
1391
            {
1392
//                debug("$cur has no children");
1393
                $my_tree .= '<li>'.$this->returnSee($tree[$cur]['link'])."</li>";
1394
                if ($dopar && $cur == '#root') $my_tree .= '</ul></li>';
1395
                $cur = array_pop($lastcur);
1396
            }
1397
        } while ($cur);
1398
        return $my_tree;
1399
    }
1400
 
1401
    /**
1402
     * Generate indexing information for given element
1403
     *
1404
     * @param parserElement descendant of parserElement
1405
     * @see generateElementIndex()
1406
     * @return array
1407
     */
1408
    function getIndexInformation($elt)
1409
    {
1410
        $Result['type'] = $elt->type;
1411
        $Result['file_name'] = $elt->file;
1412
        $Result['path'] = $elt->getPath();
1413
 
1414
        if (isset($elt->docblock))
1415
					{
1416
						$Result['description'] = $elt->docblock->getSDesc($this);
1417
 
1418
						if ($elt->docblock->hasaccess)
1419
							$Result['access'] = $elt->docblock->tags['access'][0]->value;
1420
						else
1421
							$Result['access'] = 'public';
1422
 
1423
						$Result['abstract'] = isset ($elt->docblock->tags['abstract'][0]);
1424
					}
1425
        else
1426
            $Result['description'] = '';
1427
 
1428
        $aa = $Result['description'];
1429
        if (!empty($aa)) $aa = "<br>&nbsp;&nbsp;&nbsp;&nbsp;$aa";
1430
 
1431
        switch($elt->type)
1432
        {
1433
                case 'class':
1434
                        $Result['name'] = $elt->getName();
1435
                        $Result['title'] = 'Class';
1436
                        $Result['link'] = $this->getClassLink($elt->getName(),
1437
                                                              $elt->docblock->package,
1438
                                                              $elt->getPath(),
1439
                                                              $elt->getName());
1440
                        $Result['listing'] = 'in file '.$elt->file.', class '.$Result['link']."$aa";
1441
                break;
1442
                case 'define':
1443
                        $Result['name'] = $elt->getName();
1444
                        $Result['title'] = 'Constant';
1445
                        $Result['link'] = $this->getDefineLink($elt->getName(),
1446
                                                               $elt->docblock->package,
1447
                                                               $elt->getPath(),
1448
                                                               $elt->getName());
1449
                        $Result['listing'] = 'in file '.$elt->file.', constant '.$Result['link']."$aa";
1450
                break;
1451
                case 'global':
1452
                        $Result['name'] = $elt->getName();
1453
                        $Result['title'] = 'Global';
1454
                        $Result['link'] = $this->getGlobalLink($elt->getName(),
1455
                                                               $elt->docblock->package,
1456
                                                               $elt->getPath(),
1457
                                                               $elt->getName());
1458
                        $Result['listing'] = 'in file '.$elt->file.', global variable '.$Result['link']."$aa";
1459
                break;
1460
                case 'function':
1461
                        $Result['name'] = $elt->getName();
1462
                        $Result['title'] = 'Function';
1463
                        $Result['link'] = $this->getFunctionLink($elt->getName(),
1464
                                                                 $elt->docblock->package,
1465
                                                                 $elt->getPath(),
1466
                                                                 $elt->getName().'()');
1467
                        $Result['listing'] = 'in file '.$elt->file.', function '.$Result['link']."$aa";
1468
                break;
1469
                case 'method':
1470
                        $Result['name'] = $elt->getName();
1471
                        $Result['title'] = 'Method';
1472
                        $Result['link'] = $this->getMethodLink($elt->getName(),
1473
                                                               $elt->class,
1474
                                                               $elt->docblock->package,
1475
                                                               $elt->getPath(),
1476
                                                               $elt->class.'::'.$elt->getName().'()'
1477
                                                                         );
1478
													if ($elt->isConstructor) $Result['constructor'] = 1;
1479
                        $Result['listing'] = 'in file '.$elt->file.', method '.$Result['link']."$aa";
1480
                break;
1481
                case 'var':
1482
                        $Result['name'] = $elt->getName();
1483
                        $Result['title'] = 'Variable';
1484
                        $Result['link'] = $this->getVarLink($elt->getName(),
1485
                                                            $elt->class,
1486
                                                            $elt->docblock->package,
1487
                                                            $elt->getPath(),
1488
                                                            $elt->class.'::'.$elt->getName());
1489
                        $Result['listing'] = 'in file '.$elt->file.', variable '.$Result['link']."$aa";
1490
                break;
1491
                case 'const':
1492
                        $Result['name'] = $elt->getName();
1493
                        $Result['title'] = 'Class Constant';
1494
                        $Result['link'] = $this->getConstLink($elt->getName(),
1495
                                                            $elt->class,
1496
                                                            $elt->docblock->package,
1497
                                                            $elt->getPath(),
1498
                                                            $elt->class.'::'.$elt->getName());
1499
                        $Result['listing'] = 'in file '.$elt->file.', class constant '.$Result['link']."$aa";
1500
                break;
1501
                case 'page':
1502
                        $Result['name'] = $elt->getFile();
1503
                        $Result['title'] = 'Page';
1504
                        $Result['link'] = $this->getPageLink($elt->getFile(),
1505
                                                             $elt->package,
1506
                                                             $elt->getPath(),
1507
                                                             $elt->getFile());
1508
                        $Result['listing'] = 'procedural page '.$Result['link'];
1509
                break;
1510
                case 'include':
1511
                        $Result['name'] = $elt->getName();
1512
                        $Result['title'] = 'Include';
1513
                        $Result['link'] = $elt->getValue();
1514
                        $Result['listing'] = 'include '.$Result['name'];
1515
                break;
1516
        }
1517
 
1518
        return $Result;
1519
    }
1520
    /**
1521
     * Generate alphabetical index of all elements
1522
     *
1523
     * @see $elements, walk()
1524
     */
1525
    function generateElementIndex()
1526
    {
1527
        $elementindex = array();
1528
        $letters = array();
1529
        $used = array();
1530
        foreach($this->elements as $letter => $nutoh)
1531
        {
1532
            foreach($this->elements[$letter] as $i => $yuh)
1533
            {
1534
                if ($this->elements[$letter][$i]->type != 'include')
1535
                {
1536
                    if (!isset($used[$letter]))
1537
                    {
1538
                        $letters[]['letter'] = $letter;
1539
                        $elindex['letter'] = $letter;
1540
                        $used[$letter] = 1;
1541
                    }
1542
 
1543
                    $elindex['index'][] = $this->getIndexInformation($this->elements[$letter][$i]);
1544
                }
1545
            }
1546
            if (isset($elindex['index']))
1547
            {
1548
                $elementindex[] = $elindex;
1549
            } else
1550
            {
1551
                unset($letters[count($letters) - 1]);
1552
            }
1553
            $elindex = array();
1554
        }
1555
        return array($elementindex,$letters);
1556
    }
1557
 
1558
    function copyMediaRecursively($media,$targetdir,$subdir = '')
1559
    {
1560
        $versionControlDirectories = array ('CVS', 'media/CVS', 'media\\CVS', '.svn', 'media/.svn', 'media\\.svn');
1561
        if (!is_array($media)) {
1562
            return;
1563
        }
1564
        foreach($media as $dir => $files)
1565
        {
1566
            if ($dir === '/')
1567
            {
1568
                $this->copyMediaRecursively($files,$targetdir);
1569
            } else
1570
            {
1571
                if (!is_numeric($dir))
1572
                {
1573
                    if (in_array($dir, $versionControlDirectories))
1574
                    {
1575
                        // skip it entirely
1576
                    }
1577
                    else
1578
                    {
1579
                        // create the subdir
1580
                        phpDocumentor_out("creating $targetdir" . PATH_DELIMITER . "$dir\n");
1581
                        Converter::setTargetDir($targetdir . PATH_DELIMITER . $dir);
1582
                        if (!empty($subdir))
1583
                        {
1584
                            $subdir .= PATH_DELIMITER;
1585
                        }
1586
                        $this->copyMediaRecursively($files,"$targetdir/$dir",$subdir . $dir);
1587
                    }
1588
                }
1589
                else
1590
                {
1591
                    // copy the file
1592
                    phpDocumentor_out("copying $targetdir" . PATH_DELIMITER . $files['file']."\n");
1593
                    $this->copyFile($files['file'],$subdir);
1594
                }
1595
            }
1596
        }
1597
    }
1598
 
1599
    /**
1600
     * calls the converter setTargetDir, and then copies any template images and the stylesheet if they haven't been copied
1601
     * @see Converter::setTargetDir()
1602
     */
1603
    function setTargetDir($dir)
1604
    {
1605
        Converter::setTargetDir($dir);
1606
        if ($this->wrote) return;
1607
        $this->wrote = true;
1608
        $template_images = array();
1609
        $stylesheets = array();
1610
        $tdir = $dir;
1611
        $dir = $this->templateDir;
1612
        $this->templateDir = $this->templateDir.'templates/';
1613
        $info = new Io;
1614
        $this->copyMediaRecursively($info->getDirTree($this->templateDir.'media',$this->templateDir),$tdir);
1615
    }
1616
 
1617
    /**
1618
     * Generate alphabetical index of all elements by package and subpackage
1619
     *
1620
     * @param string $package name of a package
1621
     * @see $pkg_elements, walk(), generatePkgElementIndexes()
1622
     */
1623
    function generatePkgElementIndex($package)
1624
    {
1625
//        var_dump($this->pkg_elements[$package]);
1626
        $elementindex = array();
1627
        $letters = array();
1628
        $letterind = array();
1629
        $used = array();
1630
        $subp = '';
1631
        foreach($this->pkg_elements[$package] as $subpackage => $els)
1632
        {
1633
            if (empty($els)) continue;
1634
            if (!empty($subpackage)) $subp = " (<b>subpackage:</b> $subpackage)"; else $subp = '';
1635
            foreach($els as $letter => $yuh)
1636
            {
1637
                foreach($els[$letter] as $i => $yuh)
1638
                {
1639
                    if ($els[$letter][$i]->type != 'include')
1640
                    {
1641
                        if (!isset($used[$letter]))
1642
                        {
1643
                            $letters[]['letter'] = $letter;
1644
                            $letterind[$letter] = count($letters) - 1;
1645
                            $used[$letter] = 1;
1646
                        }
1647
                        $elindex[$letter]['letter'] = $letter;
1648
 
1649
                        $elindex[$letter]['index'][] = $this->getIndexInformation($els[$letter][$i]);
1650
                    }
1651
                }
1652
            }
1653
        }
1654
        ksort($elindex);
1655
        usort($letters,'HTMLframes_lettersort');
1656
        if (isset($elindex))
1657
        {
1658
            while(list($letter,$tempel) = each($elindex))
1659
            {
1660
                if (!isset($tempel))
1661
                {
1662
                    unset($letters[$letterind[$tempel['letter']]]);
1663
                } else
1664
                $elementindex[] = $tempel;
1665
            }
1666
        } else $letters = array();
1667
        return array($elementindex,$letters);
1668
    }
1669
 
1670
    /**
1671
     *
1672
     * @see generatePkgElementIndex()
1673
     */
1674
    function generatePkgElementIndexes()
1675
    {
1676
        $packages = array();
1677
        $package_names = array();
1678
        $pkg = array();
1679
        $letters = array();
1680
        foreach($this->pkg_elements as $package => $trash)
1681
        {
1682
            $pkgs['package'] = $package;
1683
            $pkg['package'] = $package;
1684
            list($pkg['pindex'],$letters[$package]) = $this->generatePkgElementIndex($package);
1685
            if (count($pkg['pindex']))
1686
            {
1687
                $packages[] = $pkg;
1688
                $package_names[] = $pkgs;
1689
            }
1690
            unset($pkgs);
1691
            unset($pkg);
1692
        }
1693
        foreach($packages as $i => $package)
1694
        {
1695
            $pnames = array();
1696
            for($j=0;$j<count($package_names);$j++)
1697
            {
1698
                if ($package_names[$j]['package'] != $package['package']) $pnames[] = $package_names[$j];
1699
            }
1700
            $packages[$i]['packageindexes'] = $pnames;
1701
        }
1702
        return array($packages,$package_names,$letters);
1703
    }
1704
 
1705
    /**
1706
     * @param string name of class
1707
     * @param string package name
1708
     * @param string full path to look in (used in index generation)
1709
     * @param boolean deprecated
1710
     * @param boolean return just the URL, or enclose it in an html a tag
1711
     * @return mixed false if not found, or an html a link to the class's documentation
1712
     * @see parent::getClassLink()
1713
     */
1714
    function getClassLink($expr,$package, $file = false,$text = false, $with_a = true)
1715
    {
1716
        $a = Converter::getClassLink($expr,$package,$file);
1717
        if (!$a) return false;
1718
        return $this->returnSee($a, $text, $with_a);
1719
    }
1720
 
1721
    /**
1722
     * @param string name of function
1723
     * @param string package name
1724
     * @param string full path to look in (used in index generation)
1725
     * @param boolean deprecated
1726
     * @param boolean return just the URL, or enclose it in an html a tag
1727
     * @return mixed false if not found, or an html a link to the function's documentation
1728
     * @see parent::getFunctionLink()
1729
     */
1730
    function getFunctionLink($expr,$package, $file = false,$text = false)
1731
    {
1732
        $a = Converter::getFunctionLink($expr,$package,$file);
1733
        if (!$a) return false;
1734
        return $this->returnSee($a, $text);
1735
    }
1736
 
1737
    /**
1738
     * @param string name of define
1739
     * @param string package name
1740
     * @param string full path to look in (used in index generation)
1741
     * @param boolean deprecated
1742
     * @param boolean return just the URL, or enclose it in an html a tag
1743
     * @return mixed false if not found, or an html a link to the define's documentation
1744
     * @see parent::getDefineLink()
1745
     */
1746
    function getDefineLink($expr,$package, $file = false,$text = false)
1747
    {
1748
        $a = Converter::getDefineLink($expr,$package,$file);
1749
        if (!$a) return false;
1750
        return $this->returnSee($a, $text);
1751
    }
1752
 
1753
    /**
1754
     * @param string name of global variable
1755
     * @param string package name
1756
     * @param string full path to look in (used in index generation)
1757
     * @param boolean deprecated
1758
     * @param boolean return just the URL, or enclose it in an html a tag
1759
     * @return mixed false if not found, or an html a link to the global variable's documentation
1760
     * @see parent::getGlobalLink()
1761
     */
1762
    function getGlobalLink($expr,$package, $file = false,$text = false)
1763
    {
1764
        $a = Converter::getGlobalLink($expr,$package,$file);
1765
        if (!$a) return false;
1766
        return $this->returnSee($a, $text);
1767
    }
1768
 
1769
    /**
1770
     * @param string name of procedural page
1771
     * @param string package name
1772
     * @param string full path to look in (used in index generation)
1773
     * @param boolean deprecated
1774
     * @param boolean return just the URL, or enclose it in an html a tag
1775
     * @return mixed false if not found, or an html a link to the procedural page's documentation
1776
     * @see parent::getPageLink()
1777
     */
1778
    function getPageLink($expr,$package, $path = false,$text = false)
1779
    {
1780
        $a = Converter::getPageLink($expr,$package,$path);
1781
        if (!$a) return false;
1782
        return $this->returnSee($a, $text);
1783
    }
1784
 
1785
    /**
1786
     * @param string name of method
1787
     * @param string class containing method
1788
     * @param string package name
1789
     * @param string full path to look in (used in index generation)
1790
     * @param boolean deprecated
1791
     * @param boolean return just the URL, or enclose it in an html a tag
1792
     * @return mixed false if not found, or an html a link to the method's documentation
1793
     * @see parent::getMethodLink()
1794
     */
1795
    function getMethodLink($expr,$class,$package, $file = false,$text = false)
1796
    {
1797
        $a = Converter::getMethodLink($expr,$class,$package,$file);
1798
        if (!$a) return false;
1799
        return $this->returnSee($a, $text);
1800
    }
1801
 
1802
    /**
1803
     * @param string name of var
1804
     * @param string class containing var
1805
     * @param string package name
1806
     * @param string full path to look in (used in index generation)
1807
     * @param boolean deprecated
1808
     * @param boolean return just the URL, or enclose it in an html a tag
1809
     * @return mixed false if not found, or an html a link to the var's documentation
1810
     * @see parent::getVarLink()
1811
     */
1812
    function getVarLink($expr,$class,$package, $file = false,$text = false)
1813
    {
1814
        $a = Converter::getVarLink($expr,$class,$package,$file);
1815
        if (!$a) return false;
1816
        return $this->returnSee($a, $text);
1817
    }
1818
 
1819
    /**
1820
     * @param string name of class constant
1821
     * @param string class containing class constant
1822
     * @param string package name
1823
     * @param string full path to look in (used in index generation)
1824
     * @param boolean deprecated
1825
     * @param boolean return just the URL, or enclose it in an html a tag
1826
     * @return mixed false if not found, or an html a link to the var's documentation
1827
     * @see parent::getVarLink()
1828
     */
1829
    function getConstLink($expr,$class,$package, $file = false,$text = false)
1830
    {
1831
        $a = Converter::getConstLink($expr,$class,$package,$file);
1832
        if (!$a) return false;
1833
        return $this->returnSee($a, $text);
1834
    }
1835
 
1836
    /**
1837
     * does a nat case sort on the specified second level value of the array
1838
     *
1839
     * @param    mixed    $a
1840
     * @param    mixed    $b
1841
     * @return    int
1842
     */
1843
    function rcNatCmp ($a, $b)
1844
    {
1845
        $aa = strtoupper($a[$this->rcnatcmpkey]);
1846
        $bb = strtoupper($b[$this->rcnatcmpkey]);
1847
 
1848
        return strnatcasecmp($aa, $bb);
1849
    }
1850
 
1851
    /**
1852
     * does a nat case sort on the specified second level value of the array.
1853
     * this one puts constructors first
1854
     *
1855
     * @param    mixed    $a
1856
     * @param    mixed    $b
1857
     * @return    int
1858
     */
1859
    function rcNatCmp1 ($a, $b)
1860
    {
1861
        $aa = strtoupper($a[$this->rcnatcmpkey]);
1862
        $bb = strtoupper($b[$this->rcnatcmpkey]);
1863
 
1864
        if (strpos($aa,'CONSTRUCTOR') === 0)
1865
        {
1866
            return -1;
1867
        }
1868
        if (strpos($bb,'CONSTRUCTOR') === 0)
1869
        {
1870
            return 1;
1871
        }
1872
        if (strpos($aa,strtoupper($this->class)) === 0)
1873
        {
1874
            return -1;
1875
        }
1876
        if (strpos($bb,strtoupper($this->class)) === 0)
1877
        {
1878
            return -1;
1879
        }
1880
        return strnatcasecmp($aa, $bb);
1881
    }
1882
 
1883
    /**
1884
     * This function is not used by HTMLdefaultConverter, but is required by Converter
1885
     */
1886
    function Output()
1887
    {
1888
    }
1889
}
1890
 
1891
/**
1892
 * @access private
1893
 * @global string name of the package to set as the first package
1894
 */
1895
function HTMLframes_pindexcmp($a, $b)
1896
{
1897
    global $phpDocumentor_DefaultPackageName;
1898
    if ($a['title'] == $phpDocumentor_DefaultPackageName) return -1;
1899
    if ($b['title'] == $phpDocumentor_DefaultPackageName) return 1;
1900
    return strnatcasecmp($a['title'],$b['title']);
1901
}
1902
 
1903
/** @access private */
1904
function HTMLframes_lettersort($a, $b)
1905
{
1906
    return strnatcasecmp($a['letter'],$b['letter']);
1907
}
1908
 
1909
/** @access private */
1910
function HTMLframes_outputfilter($src, &$smarty)
1911
{
1912
    return str_replace('{$subdir}',$smarty->_tpl_vars['subdir'],$src);
1913
}
1914
?>