Subversion Repositories Applications.papyrus

Rev

Rev 1371 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
954 florian 1
<?php
2
# ***** BEGIN LICENSE BLOCK *****
3
# This file is part of DotClear.
4
# Copyright (c) 2004 Olivier Meunier and contributors. All rights
5
# reserved.
6
#
7
# DotClear is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 2 of the License, or
10
# (at your option) any later version.
11
#
12
# DotClear is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with DotClear; if not, write to the Free Software
19
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
#
21
# ***** END LICENSE BLOCK *****
22
 
23
/*
24
Classe de gestion des plugins et des thèmes
25
*/
26
 
27
class plugins
28
{
29
	var $location;
30
	var $type;
31
	var $_xml;
32
	var $p_list = array();
33
 
34
	function plugins($location,$type='plugin')
35
	{
36
		if (is_dir($location)) {
37
			$this->location = $location.'/';
38
		} else {
39
			$this->location = NULL;
40
		}
41
 
42
		$this->type = $type;
43
	}
44
 
45
	function getPlugins($active_only=true)
46
	{
47
		if (($list_files = $this->_readDir()) !== false)
48
		{
49
			$this->p_list = array();
50
			foreach ($list_files as $entry => $pfile)
51
			{
52
				if (($info = $this->_getPluginInfo($pfile)) !== false) {
53
					if (($active_only && $info['active']) || !$active_only) {
54
						$this->p_list[$entry] = $info;
55
					}
56
				}
57
			}
58
			ksort($this->p_list);
59
			return true;
60
		}
61
		else
62
		{
63
			return false;
64
		}
65
	}
66
 
67
	function getPluginsList()
68
	{
69
		return $this->p_list;
70
	}
71
 
72
	function getFunctions($f='functions.php')
73
	{
74
		$res = array();
75
 
76
		if (($list_files = $this->_readDir()) !== false)
77
		{
78
			foreach ($list_files as $entry => $pfile)
79
			{
80
				if (file_exists(dirname($pfile).'/'.$f)) {
81
					$res[] = dirname($pfile).'/'.$f;
82
				}
83
			}
84
		}
85
		return $res;
86
	}
87
 
88
	function loadCallbacks()
89
	{
90
		$res['onPost'] = array();
91
 
92
		$ires = array_keys($res);
93
 
94
		foreach ($this->p_list as $k => $v)
95
		{
96
			# Chargement des fichiers events.php
97
 
98
			if (file_exists($this->location.$k.'/events.php'))
99
			{
100
				require_once $this->location.$k.'/events.php';
101
 
102
				foreach ($v['callbacks'] as $f)
103
				{
104
					if (in_array($f[0],$ires))
105
					{
106
						$pf = explode('::',$f[1]);
107
						if (count($pf) == 2 && is_callable($pf)) {
108
							$res[$f[0]][] = $pf;
109
						}
110
					}
111
				}
112
			}
113
		}
114
 
115
		return $res;
116
	}
117
 
118
	function loadl10n($p)
119
	{
120
		if (defined('DC_LANG')) {
121
			if (dc_encoding == 'UTF-8') {
122
				l10n::set($this->location.$p.'/l10n/'.DC_LANG.'-utf8/main');
123
			} else {
124
				l10n::set($this->location.$p.'/l10n/'.DC_LANG.'/main');
125
			}
126
		}
127
	}
128
 
129
	function switchStatus($p)
130
	{
131
		$xml_path = $this->location.$p.'/desc.xml';
132
		$p_info = $this->_getPluginInfo($xml_path);
133
		$xml = implode('',file($xml_path));
134
 
135
		$active = (integer) !$p_info['active'];
136
 
137
		$xml = preg_replace('|(<'.$this->type.'[^>]*?active=)"([^"]+)([^>]*>)|ms',
138
			'$1"'.$active.'$3',$xml);
139
 
140
		if (!files::putContent($xml_path,$xml)) {
141
			return false;
142
		}
143
		return true;
144
	}
145
 
146
 
147
	/* Installation d'un plugin */
148
	function install($url)
149
	{
150
		$dest = $this->location.'/'.basename($url);
151
		if (($err = files::copyRemote($url,$dest)) !== true)
152
		{
153
			return $err;
154
		}
155
		else
156
		{
157
			if (($content = @implode('',@gzfile($dest))) === false) {
158
				return __('Cannot open file');
159
			} else {
160
				if (($list = unserialize($content)) === false)
161
				{
162
					return __('Plugin not valid');
163
				}
164
				else
165
				{
166
					if (is_dir($this->location.'/'.$list['name']))
167
					{
168
						/*if (files::deltree($this->location.'/'.$list['name']) === false)
169
						{
170
							return 'Impossible de supprimer le plugin existant';
171
						}*/
172
						unlink($dest);
173
						return __('This plugin still exists. Delete it before.');
174
					}
175
 
176
					foreach ($list['dirs'] as $d)
177
					{
178
						mkdir ($this->location.'/'.$d,fileperms($this->location));
179
						chmod($this->location.'/'.$d,fileperms($this->location));
180
					}
181
 
182
					foreach ($list['files'] as $f => $v)
183
					{
184
						$v = base64_decode($v);
185
						$fp = fopen($this->location.'/'.$f,'w');
186
						fwrite($fp,$v,strlen($v));
187
						fclose($fp);
188
						chmod($this->location.'/'.$f,fileperms($this->location) & ~0111);
189
					}
190
 
191
					unlink($dest);
192
				}
193
			}
194
		}
195
		return true;
196
	}
197
 
198
	/* Lecture d'un répertoire à la recherche des desc.xml */
199
	function _readDir()
200
	{
201
		if ($this->location === NULL) {
202
			return false;
203
		}
204
 
205
		$res = array();
206
 
207
		$d = dir($this->location);
208
 
209
		# Liste du répertoire des plugins
210
		while (($entry = $d->read()) !== false)
211
		{
212
			if ($entry != '.' && $entry != '..' &&
213
			is_dir($this->location.$entry) && file_exists($this->location.$entry.'/desc.xml'))
214
			{
215
				$res[$entry] = $this->location.$entry.'/desc.xml';
216
			}
217
		}
218
 
219
		return $res;
220
	}
221
 
222
	function _getPluginInfo($p)
223
	{
224
		if (file_exists($p))
225
		{
226
			$this->_current_tag_cdata = '';
227
			$this->_p_info = array('name'=>NULL,'version'=>NULL,
228
						'active'=>NULL,'author'=>NULL,'label'=>NULL,
229
						'desc'=>NULL,'callbacks'=>array());
230
 
231
			$this->_xml = xml_parser_create('ISO-8859-1');
232
			xml_parser_set_option($this->_xml, XML_OPTION_CASE_FOLDING, false);
233
			xml_set_object($this->_xml, $this);
234
			xml_set_element_handler($this->_xml,'_openTag','_closeTag');
235
			xml_set_character_data_handler($this->_xml, '_cdata');
236
 
237
			xml_parse($this->_xml,implode('',file($p)));
238
			xml_parser_free($this->_xml);
239
 
240
			if (!empty($this->_p_info['name'])) {
241
				return $this->_p_info;
242
			} else {
243
				return false;
244
			}
245
		}
246
	}
247
 
248
	function _openTag($p,$tag,$attr)
249
	{
250
		if ($tag == $this->type && !empty($attr['name']))
251
		{
252
			$this->_p_info['name'] = $attr['name'];
253
			$this->_p_info['version'] = (!empty($attr['version'])) ? $attr['version'] : NULL;
254
			$this->_p_info['active'] = (!empty($attr['active'])) ? (boolean) $attr['active'] : false;
255
		}
256
 
257
		if ($tag == 'callback') {
258
			$this->_p_info['callbacks'][] = array($attr['event'],$attr['function']);
259
		}
260
	}
261
 
262
	function _closeTag($p,$tag)
263
	{
264
		switch ($tag)
265
		{
266
			case 'author':
267
			case 'label':
268
			case 'desc':
269
				$this->_p_info[$tag] = $this->_current_tag_cdata;
270
				break;
271
		}
272
	}
273
 
274
	function _cdata($p,$cdata)
275
	{
276
		$this->_current_tag_cdata = $cdata;
277
	}
278
}
279
 
280
?>