1<?php
2
3/**
4 * manages the display layout of the project files on the wiki page
5 *
6 */
7
8require_once(dirname(__FILE__).'/../conf.php');
9require_once(dirname(__FILE__).'/tools.php');
10
11class ProjectFileLayout {
12    protected $project = NULL;
13	protected $ID = NULL;
14	protected $file_name = NULL;
15	protected $file = NULL;
16	protected $errors = NULL;
17	protected $layour = NULL;
18	protected $tag = NULL;
19	protected $header = NULL;
20	protected $name = NULL;
21	protected $content = NULL;
22	protected $failure = false;
23
24	public function __construct($project, $ID, $file) {
25		$this->ID = $ID;
26		$this->file_name = array_pop(explode(":", $ID));
27		$this->project = $project;
28		$this->file = $file;
29	}
30
31	private function set_errors(&$renderer) {
32		if ($this->project == NULL) {
33			$renderer->doc .= "<div class=\"project_file_errors\">";
34			$this->add_error($renderer, htmlspecialchars('<' . PROJECTS_TAG . '>') .
35				" tags can only be used in \"" . PROJECTS_NAMESPACE .
36				'" namespace. ' .
37				"The following project file does not have any effect!");
38			$renderer->doc .= "</div>";
39			return;
40		}
41		$errors = $this->project->error($this->file_name);
42		if (!$errors) return;
43		$renderer->doc .= "<div class=\"project_file_errors\">";
44		foreach ($errors as $error) {
45			if ($error == 'undefined') {
46				$this->add_error($renderer, "Do not know how to generate the file");
47				continue;
48			}
49			if (isset($error['failure'])) {
50				$this->failure = true;
51				$this->add_error($renderer,
52					"Failed to generate. see the log below.");
53				continue;
54			}
55			if (isset($error['dependency'])) {
56				$deps = $this->file->dependency();
57				$dep = $error['dependency'];
58				if (in_array($dep, $deps)) continue;
59				$dep_id = $this->project->id($dep);
60				if ($dep_id != NULL)
61					$link = "<a href=\"" . wl($dep_id) . "\">$dep</a>";
62				else $link = $dep;
63				$this->add_error($renderer,
64					"Do not know how to generate the dependency $link");
65				continue;
66			}
67			if (isset($error['loop'])) {
68				$msg = "";
69				foreach ($error['loop'] as $loop)
70					$msg .= ' ' . $loop;
71				$this->add_error($renderer, "Circular dependency:" . $msg);
72				continue;
73			}
74		}
75		$renderer->doc .= "</div>";
76	}
77
78	public function render(&$renderer) {
79		$id = $this->file_name;
80		// the whole tag
81		$renderer->doc .= "<div class=\"project_file\" id=\"$id\">";
82		$renderer->doc .= "<a name=\"$id\"></a>";
83		//header
84		$renderer->doc .= "<div class=\"project_file_header\">";
85		//type
86		$renderer->doc .= "<div class=\"tag_header\">Type</div>";
87		$type = $this->file->type();
88		$renderer->doc .= "<div class=\"project_file_type\">$type</div>";
89		//name
90		$renderer->doc .= "<div class=\"tag_header\">Name</div>";
91		$renderer->doc .= "<div class=\"project_file_name\">";
92		$this->render_name($renderer);
93		$renderer->doc .= "</div>";
94		//project
95		if ($this->project != NULL)
96			$project_name = $this->project->name();
97		else
98			$project_name = "None";
99		$renderer->doc .= "<div class=\"tag_header\">in project</div>";
100		$renderer->doc .=
101			"<div class=\"project_file_project\">$project_name";
102		// close project
103		$renderer->doc .= "</div>";
104		//buttons
105		$renderer->doc .= "<div class=\"spacer\"></div>";
106		$renderer->doc .= "<div class=\"project_file_buttons\">";
107		$this->render_buttons($renderer);
108		$renderer->doc .= "</div>";
109		//close header
110		$renderer->doc .= "</div>";
111		$this->set_errors($renderer);
112		$renderer->doc .= "<div class=\"project_file_content\">";
113		$renderer->doc .= $this->render_content($renderer);
114		// close content
115		$renderer->doc .= "</div>";
116		$renderer->doc .= "</div>";
117	}
118
119	protected function render_name(&$renderer) {
120		$renderer->doc .= $this->file_name;
121	}
122
123	protected function render_content(&$renderer) {}
124
125	protected function render_buttons(&$renderer) {
126		global $ID;
127        $renderer->doc .= button_add("Add dependency", USE_TAG);
128		$renderer->doc .= button_delete($this->project->id($this->file_name));
129		if ($this->project == NULL) return;
130		$renderer->doc .= action_button("Manage files", 'manage_files');
131	}
132
133	public function add_error(&$renderer, $error) {
134		$renderer->doc .= "<div class=\"error\">$error</div>";
135	}
136}
137
138class TargetLayout extends ProjectFileLayout {
139	private $link = NULL;
140	private $display = NULL;
141
142	public function __construct($project, $ID, $file) {
143		parent::__construct($project, $ID, $file);
144		if ($project != NULL) $this->link = ml($ID);
145		$this->display = $file->attribute('display');
146	}
147
148	protected function render_name(&$renderer) {
149		if ($this->display == 'link')
150			$renderer->internalmedia($this->file_name, NULL, NULL, NULL, NULL, NULL, 'linkonly');
151		else parent::render_name($renderer);
152	}
153
154	protected function render_content(&$renderer) {
155		if ($this->display_link) return;
156		$name = $this->file_name;
157		$link = $this->link;
158		if ($this->failure) {
159			$renderer->preformatted(file_get_contents(
160				$this->project->path() . $name . '.make.log'));
161			return;
162		}
163        $this->render_file_content($renderer);
164    }
165
166    protected function render_file_content(&$renderer) {
167        $name = $this->file_name;
168        $renderer->internalmedia($this->project->id($name));
169        if (!isset($attributes['display']) ||
170            $attributes['display'] != 'link') {
171            $mime = file_mimetype($this->ID, $this->project);
172          if (substr($mime, 0, 5) == 'text/' || $mime == 'plain/text')
173                render_code($renderer, file_get_contents(
174                    $this->project->path() . $name), 'unspecified');
175        }
176	}
177
178	protected function render_buttons(&$renderer) {
179		global $ID;
180		if (auth_quickaclcheck($ID) > AUTH_READ)
181			$renderer->doc .= button_remake($this->project->id($this->file_name));
182		parent::render_buttons($renderer);
183	}
184}
185
186class CrossLinkLayout extends TargetLayout {
187	private $crosslink = NULL;
188	private $media = FALSE;
189	public function __construct($project, $name, $file) {
190		parent::__construct($project, $name, $file);
191		$this->crosslink = $file->crosslink();
192        $path = explode(':', $this->crosslink);
193        $this->media = ($path[0] == '[media]');
194        if ($this->media) array_shift($path);
195        $id = implode(':', $path);
196        if (!getNS($id)) $id = $project->id($id);
197        $this->crosslink = $id;
198	}
199
200	protected function render_file_content(&$renderer) {
201		$renderer->doc .= "<div class=\"crosslink\">";
202		$path = explode(':', $this->crosslink);
203		if ($path[0] == PROJECTS_NAMESPACE) {
204        	if ($this->media)
205			    $renderer->doc .= '<a href="' . ml($this->crosslink) . '">' . $this->crosslink . '</a>';
206            else
207			    $renderer->doc .= html_wikilink($this->crosslink);
208		}
209		$renderer->doc .= "</div>";
210	}
211}
212
213?>