1<?php
2/**
3 * FileDefinition and its children: classes that declare a wiki page to
4 * be a project file with the same name.
5 *
6 * @author     Junling Ma <junlingm@gmail.com>
7 */
8
9require_once(dirname(__FILE__).'/../conf.php');
10require_once(dirname(__FILE__).'/tools.php');
11
12class FileDefinition {
13	// the attributes like name and type
14	private $attributes = array();
15	// the dependency
16	private $deps = array();
17	// the beginning and end position in the wiki page
18	public $end = NULL;
19	public $position = NULL;
20
21	public function __construct($attributes) {
22		$this->attributes = $attributes;
23	}
24
25	public function attributes() { return $this->attributes; }
26
27	public function attribute($name) {
28		if (!isset($this->attributes[$name])) return NULL;
29		return $this->attributes[$name];
30	}
31
32	public function name() { return $this->attribute('name'); }
33	public function type() { return $this->attribute('type'); }
34
35	public function dependency() { return $this->deps; }
36	public function add_dependency($name) {
37		if (!in_array($name, $this->deps)) $this->deps[] = $name;
38	}
39
40	public static function parse($name, $tag) {
41		$xml = DOMDocument::loadXML($tag);
42		if ($xml == false) return NULL;
43		$attributes = array();
44		foreach ($xml->firstChild->attributes as $attribute)
45			$attributes[$attribute->name] = $attribute->value;
46		$attributes['name'] = $name;
47		if (!isset($attributes['type'])) return NULL;
48		$type = $attributes['type'];
49		if ($type == SOURCE)
50			return new SourceDefinition($attributes);
51		if ($type == TARGET)
52			return new TargetDefinition($attributes);
53		if ($type == CROSSLINK)
54			return new CrosslinkDefinition($attributes);
55		return NULL;
56	}
57}
58
59Class SourceDefinition extends FileDefinition {
60	private $content = NULL;
61
62	public function is_target() { return false; }
63	public function content() { return $this->content; }
64	public function add_content($content) {
65		$this->content .= $content;
66	}
67}
68
69Class TargetDefinition extends FileDefinition {
70	private $recipe = NULL;
71	public function is_target() { return true; }
72	public function recipe() { return $this->recipe; }
73	public function add_recipe($recipe) {
74		$this->recipe .= "\n" . $recipe;
75		trim($this->recipe);
76	}
77}
78
79Class CrossLinkDefinition extends FileDefinition {
80	public function is_target() { return true; }
81	public function __construct($attributes) {
82		if (!isset($attributes['linkto']))
83			$attributes['linkto'] = "";
84		else {
85			$linkto = $attributes['linkto'];
86			if (strpos($linkto, "/")) $linkto = "";
87			else if (strpos($linkto, "\\")) $linkto = "";
88			if ($linkto) {
89				$path = explode(":", $linkto);
90				if ($path[0] == '[media]') array_shift($path);
91                if (count($path) > 1 && $path[0] != PROJECTS_NAMESPACE) $linkto = "";
92			}
93			$attributes['linkto'] = $linkto;
94		}
95		parent::__construct($attributes);
96	}
97
98	public function crosslink() {
99		return trim($this->attribute('linkto'));
100	}
101	public function recipe() { return NULL; }
102}