Merge lp:~quam-plures-core/quam-plures/qp5_smallstep into lp:quam-plures

Proposed by EdB
Status: Merged
Merged at revision: 7658
Proposed branch: lp:~quam-plures-core/quam-plures/qp5_smallstep
Merge into: lp:quam-plures
Diff against target: 16242 lines (+6594/-6617)
19 files modified
qp_inc/_application.php (+1/-1)
qp_inc/_core/_template.funcs.php (+111/-140)
qp_inc/_core/model/__core.install.php (+279/-277)
qp_inc/files/files.ctrl.php (+1234/-1268)
qp_inc/plugins/_plugin.class.php (+2155/-2427)
qp_inc/users/model/_user.class.php (+976/-887)
qp_inc/users/users.ctrl.php (+709/-698)
qp_inc/users/views/_user.form.php (+283/-267)
qp_install/_functions_dbupgrade.php (+22/-0)
qp_install/_functions_install.php (+192/-195)
qp_install/index.php (+25/-28)
qp_plugins/commenttags_plugin/_commenttags.plugin.php (+15/-17)
qp_plugins/quicktags_plugin/_quicktags.plugin.php (+38/-50)
qp_plugins/smilies_plugin/_smilies.plugin.php (+45/-49)
qp_plugins/tinymce_plugin/_tinymce.plugin.php (+110/-110)
qp_rsc/js/functions.js (+11/-11)
qp_rsc/js/functions.min.js (+236/-0)
qp_templates/photoblog/index.main.php (+7/-12)
qp_view_admin/login/_login_form.main.php (+145/-180)
To merge this branch: bzr merge lp:~quam-plures-core/quam-plures/qp5_smallstep
Reviewer Review Type Date Requested Status
Quam Plures Core Team Pending
Review via email: mp+151713@code.launchpad.net

Description of the change

Ran through some quick testing and it doesn't look like anything is broken, so yay one small step :)

http://forums.quamplures.net/viewtopic.php?f=6&t=1891

To post a comment you must log in.
7660. By EdB

two more files, tested and still no problems so yay :)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'qp_inc/_application.php'
--- qp_inc/_application.php 2013-02-28 16:40:18 +0000
+++ qp_inc/_application.php 2013-03-05 23:36:23 +0000
@@ -22,7 +22,7 @@
22$files_version = '1.10';22$files_version = '1.10';
2323
24// The database version, incrememented by 1 with each change in upgrade_dbase_tables()24// The database version, incrememented by 1 with each change in upgrade_dbase_tables()
25$app_db_version = 15;25$app_db_version = 17;
2626
27$app_version = $files_version.'.'.$app_db_version;27$app_version = $files_version.'.'.$app_db_version;
2828
2929
=== modified file 'qp_inc/_core/_template.funcs.php'
--- qp_inc/_core/_template.funcs.php 2012-07-29 20:36:41 +0000
+++ qp_inc/_core/_template.funcs.php 2013-03-05 23:36:23 +0000
@@ -1,63 +1,37 @@
1<?php1<?php
2/**2/**
3 * This file implements misc functions that handle output of the HTML page.3 * This file implements misc functions that handle output of the HTML page
4 *4 *
5 * This file is part of Quam Plures - {@link http://quamplures.net/}5 * @author {@link http://wonderwinds.com/ Ed Bennett}
6 * See also {@link https://launchpad.net/quam-plures}.6 * @author {@link http://daniel.hahler.de/ Daniel HAHLER}
7 *7 * @author {@link http://fplanque.net/ Francois PLANQUE}
8 * @copyright (c) 2009 - 2011 by the Quam Plures developers - {@link http://quamplures.net/}8 * @copyright (c) 2009 by {@link http://quamplures.net/ the Quam Plures project}
9 * @copyright (c)2003-2009 by Francois PLANQUE - {@link http://fplanque.net/}9 * @license http://www.gnu.org/licenses/gpl.txt GNU General Public License v3
10 * Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.10 * @package core
11 *
12 * {@internal License choice
13 * - If you have received this file as part of a package, please find the license.txt file in
14 * the same folder or the closest folder above for complete license terms.
15 * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
16 * then you must choose one of the following licenses before using the file:
17 * - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
18 * - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
19 * }}
20 *
21 * {@internal Open Source relicensing agreement:
22 * Daniel HAHLER grants Francois PLANQUE the right to license
23 * Daniel HAHLER's contributions to this file and the b2evolution project
24 * under any OSI approved OSS license (http://www.opensource.org/licenses/).
25 * }}
26 *
27 * {@internal Below is a list of authors who have contributed to design/coding of this file: }}
28 * @author blueyed: Daniel HAHLER.
29 * @author fplanque: Francois PLANQUE.
30 *
31 * @package pond
32 */11 */
33if( !defined('QP_MAIN_INIT') ) die( 'Please, do not access this page directly.' );12if(!defined('QP_MAIN_INIT')) die('fail');
34
3513
36/**14/**
37 * T-Tag: Outputs content-type header, sets charset15 * T-Tag: Outputs content-type header, sets charset
38 */16 */
39function header_content_type( $type = 'text/html', $charset = '#' )17function header_content_type( $type = 'text/html', $charset = '#' )
40{18{
19 global $content_type_header;
41 global $io_charset;20 global $io_charset;
42 global $content_type_header;
4321
44 $content_type_header = 'Content-type: '.$type;22 $content_type_header = 'Content-type: '.$type;
4523 if( ! empty($charset) )
46 if( !empty($charset) )
47 {24 {
48 if( $charset == '#' )25 if( $charset == '#' )
49 {26 {
50 $charset = $io_charset;27 $charset = $io_charset;
51 }28 }
52
53 $content_type_header .= '; charset='.$charset;29 $content_type_header .= '; charset='.$charset;
54 }30 }
55
56 header( $content_type_header );31 header( $content_type_header );
57}32}
5833
5934
60
61/**35/**
62 * Sends HTTP header to redirect to the previous location (which36 * Sends HTTP header to redirect to the previous location (which
63 * can be given as function parameter, GET parameter (redirect_to),37 * can be given as function parameter, GET parameter (redirect_to),
@@ -78,9 +52,9 @@
78 global $Hit, $app_baseurl, $Blog, $srvc_url_sensitive;52 global $Hit, $app_baseurl, $Blog, $srvc_url_sensitive;
79 global $Session, $Debuglog, $Messages;53 global $Session, $Debuglog, $Messages;
8054
81 // TODO: fp> get this out to the caller, make a helper func like get_returnto_url()
82 if( empty($redirect_to) )55 if( empty($redirect_to) )
83 { // see if there's a redirect_to request param given:56 {
57 // see if there's a redirect_to request param given:
84 $redirect_to = param( 'redirect_to', 'string', '' );58 $redirect_to = param( 'redirect_to', 'string', '' );
8559
86 if( empty($redirect_to) )60 if( empty($redirect_to) )
@@ -91,7 +65,7 @@
91 }65 }
92 elseif( isset($Blog) && is_object($Blog) )66 elseif( isset($Blog) && is_object($Blog) )
93 {67 {
94 $redirect_to = $Blog->get('url');68 $redirect_to = $Blog->get( 'url' );
95 }69 }
96 else70 else
97 {71 {
@@ -108,7 +82,7 @@
10882
109 if( $redirect_to[0] == '/' )83 if( $redirect_to[0] == '/' )
110 {84 {
111 // TODO: until all calls to header_redirect are cleaned up:85 // @todo (0000): until all calls to header_redirect are cleaned up:
112 global $ReqHost;86 global $ReqHost;
113 $redirect_to = $ReqHost.$redirect_to;87 $redirect_to = $ReqHost.$redirect_to;
114 // debug_die( '$redirect_to must be an absolute URL' );88 // debug_die( '$redirect_to must be an absolute URL' );
@@ -122,12 +96,9 @@
122 // blueyed> Removed the removing of "action" here, as it is used to trigger certain views. Instead, "confirm(ed)?" gets removed now96 // blueyed> Removed the removing of "action" here, as it is used to trigger certain views. Instead, "confirm(ed)?" gets removed now
123 // fp> which views please (important to list in order to remove asap)97 // fp> which views please (important to list in order to remove asap)
124 // dh> sorry, don't remember98 // dh> sorry, don't remember
125 // TODO: fp> action should actually not be used to trigger views. This should be changed at some point.
126 // TODO: fp> confirm should be normalized to confirmed
127 $redirect_to = preg_replace( '~(?<=\?|&) (login|pwd|confirm(ed)?) = [^&]+ ~x', '', $redirect_to );99 $redirect_to = preg_replace( '~(?<=\?|&) (login|pwd|confirm(ed)?) = [^&]+ ~x', '', $redirect_to );
128 }100 }
129101
130 // TODO: fp> change $permanent to $status in the params
131 if( is_integer($permanent) )102 if( is_integer($permanent) )
132 {103 {
133 $status = $permanent;104 $status = $permanent;
@@ -136,7 +107,6 @@
136 {107 {
137 $status = $permanent ? 301 : 303;108 $status = $permanent ? 301 : 303;
138 }109 }
139 $Debuglog->add('Redirecting to '.$redirect_to.' (status '.$status.')');
140110
141 // Transfer of Debuglog to next page:111 // Transfer of Debuglog to next page:
142 if( $Debuglog->count('all') )112 if( $Debuglog->count('all') )
@@ -186,10 +156,10 @@
186 */156 */
187function header_nocache()157function header_nocache()
188{158{
189 header('Expires: Tue, 25 Mar 2003 05:00:00 GMT');159 header( 'Expires: Tue, 25 Mar 2003 05:00:00 GMT' );
190 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');160 header( 'Last-Modified: '.gmdate( 'D, d M Y H:i:s' ).' GMT' );
191 header('Cache-Control: no-cache, must-revalidate');161 header( 'Cache-Control: no-cache, must-revalidate' );
192 header('Pragma: no-cache');162 header( 'Pragma: no-cache' );
193}163}
194164
195165
@@ -200,28 +170,28 @@
200 *170 *
201 * <code>171 * <code>
202 * $params = array_merge( array(172 * $params = array_merge( array(
203 * 'auto_pilot' => 'none',173 * 'auto_pilot' => 'none',
204 * 'title_before' => '',174 * 'title_before' => '',
205 * 'title_after' => '',175 * 'title_after' => '',
206 * 'title_none' => '',176 * 'title_none' => '',
207 * 'title_single_disp' => true,177 * 'title_single_disp' => true,
208 * 'title_single_before' => '#', // see below178 * 'title_single_before' => '#', // see below
209 * 'title_single_after' => '#', // see below179 * 'title_single_after' => '#', // see below
210 * 'title_page_disp' => true,180 * 'title_page_disp' => true,
211 * 'title_page_before' => '#', // see below181 * 'title_page_before' => '#', // see below
212 * 'title_page_after' => '#', // see below182 * 'title_page_after' => '#', // see below
213 * 'glue' => ' - ',183 * 'glue' => ' - ',
214 * 'format' => 'htmlbody',184 * 'format' => 'htmlbody',
215 * 'arcdir_text' => T_('Archive Directory'),185 * 'arcdir_text' => T_('Archive Directory'),
216 * 'catdir_text' => T_('Category Directory'),186 * 'catdir_text' => T_('Category Directory'),
217 * 'comments_text' => T_('Latest Comments'),187 * 'comments_text' => T_('Latest Comments'),
218 * 'credits_text' => T_('Software Credits'),188 * 'credits_text' => T_('Software Credits'),
219 * 'feedback-popup_text' => T_('Feedback'),189 * 'feedback-popup_text' => T_('Feedback'),
220 * 'mediaidx_text' => T_('Photo Index'),190 * 'mediaidx_text' => T_('Photo Index'),
221 * 'msgform_text' => T_('Send an Email Message'),191 * 'msgform_text' => T_('Send an Email Message'),
222 * 'profile_text' => T_('User Profile'),192 * 'profile_text' => T_('User Profile'),
223 * 'subs_text' => T_('Subscriptions'),193 * 'subs_text' => T_('Subscriptions'),
224 * 'user_text' => T_('User'),194 * 'user_text' => T_('User'),
225 * ), $params );195 * ), $params );
226 * </code>196 * </code>
227 *197 *
@@ -232,45 +202,49 @@
232 *202 *
233 * 'auto_pilot' => 'seo_title' uses the SEO title autopilot. (default: "none")203 * 'auto_pilot' => 'seo_title' uses the SEO title autopilot. (default: "none")
234 *204 *
235 * @todo (legacy): single month: Respect locales datefmt205 * @todo (0000): single month: Respect locales datefmt
236 * @todo (legacy): single post: posts do no get proper checking (wether they are in the requested blog or wether their permissions match user rights,206 * @todo (0000): single post: posts do no get proper checking (wether they are in the requested
237 * thus the title sometimes gets displayed even when it should not. We need to pre-query the ItemList instead!!207 * blog or whether their permissions match user rights, thus the title sometimes gets displayed
238 * @todo (legacy): make it complete with all possible params!208 * even when it should not. We need to pre-query the ItemList instead!!
209 * @todo (0000): make it complete with all possible params!
239 */210 */
240function request_title( $params = array() )211function request_title( $params = array() )
241{212{
242 global $MainList, $preview, $disp;213 global $disp;
214 global $MainList;
215 global $preview;
243216
244 $params = array_merge( array(217 $params = array_merge( array(
245 'auto_pilot' => 'none',218 'auto_pilot' => 'none',
246 'title_before' => '',219 'title_before' => '',
247 'title_after' => '',220 'title_after' => '',
248 'title_none' => '',221 'title_none' => '',
249 'title_single_disp' => true,222 'title_single_disp' => true,
250 'title_single_before' => '#',223 'title_single_before' => '#',
251 'title_single_after' => '#',224 'title_single_after' => '#',
252 'title_page_disp' => true,225 'title_page_disp' => true,
253 'title_page_before' => '#',226 'title_page_before' => '#',
254 'title_page_after' => '#',227 'title_page_after' => '#',
255 'glue' => ' - ',228 'glue' => ' - ',
256 'format' => 'htmlbody',229 'format' => 'htmlbody',
257 'arcdir_text' => T_('Archive Directory'),230 'arcdir_text' => T_('Archive Directory'),
258 'catdir_text' => T_('Category Directory'),231 'catdir_text' => T_('Category Directory'),
259 'comments_text' => T_('Latest Comments'),232 'comments_text' => T_('Latest Comments'),
260 'credits_text' => T_('Software Credits'),233 'credits_text' => T_('Software Credits'),
261 'feedback-popup_text' => T_('Feedback'),234 'feedback-popup_text' => T_('Feedback'),
262 'mediaidx_text' => T_('Photo Index'),235 'mediaidx_text' => T_('Photo Index'),
263 'msgform_text' => T_('Send an Email Message'),236 'msgform_text' => T_('Send an Email Message'),
264 'profile_text' => T_('User Profile'),237 'profile_text' => T_('User Profile'),
265 'subs_text' => T_('Subscriptions'),238 'subs_text' => T_('Subscriptions'),
266 'user_text' => T_('User'),239 'user_text' => T_('User'),
267 ), $params );240 ), $params );
268241
269 if( $params['auto_pilot'] == 'seo_title' )242 if( $params['auto_pilot'] == 'seo_title' )
270 { // We want to use the SEO title autopilot. Do overrides:243 {
244 // We want to use the SEO title autopilot. Do overrides:
271 global $Blog;245 global $Blog;
272 $params['format'] = 'htmlhead';246 $params['format'] = 'htmlhead';
273 $params['title_after'] = $params['glue'].$Blog->get('name');247 $params['title_after'] = $params['glue'].$Blog->get( 'name' );
274 $params['title_single_after'] = '';248 $params['title_single_after'] = '';
275 $params['title_page_after'] = '';249 $params['title_page_after'] = '';
276 $params['title_none'] = $Blog->dget('name','htmlhead');250 $params['title_none'] = $Blog->dget('name','htmlhead');
@@ -303,7 +277,7 @@
303 global $Item;277 global $Item;
304 if( isset( $Item ) )278 if( isset( $Item ) )
305 {279 {
306 $r[] = sprintf( /* TRANS: %s is an item title */ $params['comments_text'] . T_(' on %s'), $Item->get('title') );280 $r[] = sprintf( /* TRANS: %s is an item title */ $params['comments_text'].T_(' on %s'), $Item->get('title') );
307 }281 }
308 else282 else
309 {283 {
@@ -315,7 +289,7 @@
315 // We are requesting the comments on a specific post:289 // We are requesting the comments on a specific post:
316 // Should be in first position290 // Should be in first position
317 $Item = & $MainList->get_by_idx( 0 );291 $Item = & $MainList->get_by_idx( 0 );
318 $r[] = sprintf( /* TRANS: %s is an item title */ $params['feedback-popup_text'] . T_(' on %s'), $Item->get('title') );292 $r[] = sprintf( /* TRANS: %s is an item title */ $params['feedback-popup_text'].T_(' on %s'), $Item->get('title') );
319 break;293 break;
320294
321 case 'profile':295 case 'profile':
@@ -342,13 +316,15 @@
342 case 'page':316 case 'page':
343 // We are displaying a single message:317 // We are displaying a single message:
344 if( $preview )318 if( $preview )
345 { // We are requesting a post preview:319 {
320 // We are requesting a post preview
346 $r[] = T_('PREVIEW');321 $r[] = T_('PREVIEW');
347 }322 }
348 elseif( $params['title_'.$disp.'_disp'] && isset( $MainList ) )323 elseif( $params['title_'.$disp.'_disp'] && isset( $MainList ) )
349 {324 {
350 $r = array_merge( $r, $MainList->get_filter_titles( array( 'visibility', 'hide_future' ), $params ) );325 $r = array_merge( $r, $MainList->get_filter_titles( array( 'visibility', 'hide_future' ), $params ) );
351 }326 }
327
352 if( $params['title_'.$disp.'_before'] != '#' )328 if( $params['title_'.$disp.'_before'] != '#' )
353 {329 {
354 $before = $params['title_'.$disp.'_before'];330 $before = $params['title_'.$disp.'_before'];
@@ -377,12 +353,12 @@
377 $r = implode( $params['glue'], $r );353 $r = implode( $params['glue'], $r );
378 $r = $before.format_to_output( $r, $params['format'] ).$after;354 $r = $before.format_to_output( $r, $params['format'] ).$after;
379 }355 }
380 elseif( !empty( $params['title_none'] ) )356 elseif( ! empty( $params['title_none'] ) )
381 {357 {
382 $r = $params['title_none'];358 $r = $params['title_none'];
383 }359 }
384360
385 if( !empty( $r ) )361 if( ! empty( $r ) )
386 { // We have something to display:362 { // We have something to display:
387 echo $r;363 echo $r;
388 }364 }
@@ -402,7 +378,7 @@
402 $base_tag_set = $url;378 $base_tag_set = $url;
403 echo '<base href="'.$url.'"';379 echo '<base href="'.$url.'"';
404380
405 if( !empty($target) )381 if( ! empty( $target ) )
406 {382 {
407 echo ' target="'.$target.'"';383 echo ' target="'.$target.'"';
408 }384 }
@@ -444,8 +420,7 @@
444420
445/**421/**
446 * T-Tag: Outputs a <meta name="generator"> tag which contains information about this application.422 * T-Tag: Outputs a <meta name="generator"> tag which contains information about this application.
447 *423 * @deprecated deprecated in Quam Plures v1 due to it adds no value to an installation
448 * @deprecated No longer outputs meta generator. Left for backwards compatibility
449 */424 */
450function meta_generator_tag()425function meta_generator_tag()
451{426{
@@ -462,11 +437,11 @@
462{437{
463 global $Blog, $app_baseurl;438 global $Blog, $app_baseurl;
464439
465 if( !empty( $Blog ) )440 if( ! empty( $Blog ) )
466 {441 {
467 echo $before.'<a href="'.$Blog->get( 'url' ).'">'.$blog_text.'</a>'.$after;442 echo $before.'<a href="'.$Blog->get( 'url' ).'">'.$blog_text.'</a>'.$after;
468 }443 }
469 elseif( !empty($home_text) )444 elseif( ! empty( $home_text ) )
470 {445 {
471 echo $before.'<a href="'.$app_baseurl.'">'.$home_text.'</a>'.$after;446 echo $before.'<a href="'.$app_baseurl.'">'.$home_text.'</a>'.$after;
472 }447 }
@@ -481,7 +456,6 @@
481 * If 'jquery' is used and $debug is set to true, the 'jquery_debug' is automatically swapped in.456 * If 'jquery' is used and $debug is set to true, the 'jquery_debug' is automatically swapped in.
482 * Any javascript added to the page is also added to the $required_js array, which is then checked to prevent adding the same code twice457 * Any javascript added to the page is also added to the $required_js array, which is then checked to prevent adding the same code twice
483 *458 *
484 * @todo dh>merge with require_css()
485 * @param string alias, url or filename (relative to qp_rsc/js) for javascript file459 * @param string alias, url or filename (relative to qp_rsc/js) for javascript file
486 * @param boolean Is the file's path relative to the base path/url?460 * @param boolean Is the file's path relative to the base path/url?
487 * Use false if file is in $rsc_url/js/461 * Use false if file is in $rsc_url/js/
@@ -498,9 +472,10 @@
498 '#jqueryUI_debug#' => 'jquery.ui.all.js',472 '#jqueryUI_debug#' => 'jquery.ui.all.js',
499 );473 );
500474
501 // TODO: dh> I think dependencies should get handled where the files are included!475 // @todo (0000): dh> I think dependencies should get handled where the files are included!
502 if( in_array( $js_file, array( '#jqueryUI#', '#jqueryUI_debug#' ) ) )476 if( in_array( $js_file, array( '#jqueryUI#', '#jqueryUI_debug#' ) ) )
503 { // Dependency : ensure jQuery is loaded477 {
478 // Dependency : ensure jQuery is loaded
504 require_js( '#jquery#' );479 require_js( '#jquery#' );
505 }480 }
506 elseif( $js_file == 'communication.js' )481 elseif( $js_file == 'communication.js' )
@@ -515,9 +490,9 @@
515 $js_url = $js_file;490 $js_url = $js_file;
516 $absolute = TRUE;491 $absolute = TRUE;
517 }492 }
518 elseif( !empty( $js_aliases[$js_file]) )493 elseif( ! empty( $js_aliases[$js_file]) )
519 { // It's an alias494 { // It's an alias
520 if ( $js_file == '#jquery#' && $debug ) $js_file = '#jquery_debug#';495 if( $js_file == '#jquery#' && $debug ) $js_file = '#jquery_debug#';
521 $js_file = $js_aliases[$js_file];496 $js_file = $js_aliases[$js_file];
522 }497 }
523498
@@ -546,12 +521,11 @@
546 * Accepts absolute urls, filenames relative to the qp_rsc/css directory.521 * Accepts absolute urls, filenames relative to the qp_rsc/css directory.
547 * Set $relative_to_base to TRUE to prevent this function from adding on the rsc_path522 * Set $relative_to_base to TRUE to prevent this function from adding on the rsc_path
548 *523 *
549 * @todo dh>merge with require_js()
550 * @param string alias, url or filename (relative to qp_rsc/css) for CSS file524 * @param string alias, url or filename (relative to qp_rsc/css) for CSS file
551 * @param boolean|string Is the file's path relative to the base path/url?525 * @param boolean|string Is the file's path relative to the base path/url?
552 * Use true to not add any prefix ("$rsc_url/css/").526 * Use true to not add any prefix ("$rsc_url/css/").
553 * @param string title. The title for the link tag527 * @param string The title for the link tag
554 * @param string media. ie, 'print'528 * @param string Media (ie 'print')
555 */529 */
556function require_css( $css_file, $relative_to_base = false, $title = NULL, $media = NULL )530function require_css( $css_file, $relative_to_base = false, $title = NULL, $media = NULL )
557{531{
@@ -572,7 +546,7 @@
572 }546 }
573 else547 else
574 {548 {
575 $css_url = $rsc_url . 'css/' . $css_file;549 $css_url = $rsc_url.'css/'.$css_file;
576 }550 }
577551
578 // Add to headlines, if not done already:552 // Add to headlines, if not done already:
@@ -581,11 +555,11 @@
581 $required_css[] = strtolower($css_url);555 $required_css[] = strtolower($css_url);
582556
583 $start_link_tag = '<link rel="stylesheet"';557 $start_link_tag = '<link rel="stylesheet"';
584 if ( !empty( $title ) ) $start_link_tag .= ' title="' . $title . '"';558 if( ! empty( $title ) ) $start_link_tag .= ' title="'.$title.'"';
585 if ( !empty( $media ) ) $start_link_tag .= ' media="' . $media . '"';559 if( ! empty( $media ) ) $start_link_tag .= ' media="'.$media.'"';
586 $start_link_tag .= ' type="text/css" href="';560 $start_link_tag .= ' type="text/css" href="';
587 $end_link_tag = '" />';561 $end_link_tag = '" />';
588 add_headline( $start_link_tag . $css_url . $end_link_tag );562 add_headline( $start_link_tag.$css_url.$end_link_tag );
589 }563 }
590564
591}565}
@@ -653,7 +627,7 @@
653 global $js_translations;627 global $js_translations;
654 if( $string != $translation )628 if( $string != $translation )
655 { // it's translated629 { // it's translated
656 $js_translations[ $string ] = $translation;630 $js_translations[$string] = $translation;
657 }631 }
658}632}
659633
@@ -702,11 +676,9 @@
702676
703/**677/**
704 * T-Tag: Registers all the javascripts needed by the toolbar menu678 * T-Tag: Registers all the javascripts needed by the toolbar menu
705 *679 * @todo (0000): fp> include basic.css ? -- rename to add_headlines_for* -- potential
706 * @todo (legacy): fp> include basic.css ? -- rename to add_headlines_for* -- potential680 * problem with inclusion order of CSS files!! dh> would be nice to have the batch of CSS in
707 * problem with inclusion order of CSS files!!681 * a separate file. basic.css would get included first always, then e.g. this toolbar.css.
708 * dh> would be nice to have the batch of CSS in a separate file. basic.css would
709 * get included first always, then e.g. this toolbar.css.
710 */682 */
711function add_js_for_toolbar()683function add_js_for_toolbar()
712{684{
@@ -716,8 +688,8 @@
716 }688 }
717689
718 require_js( '#jquery#' );690 require_js( '#jquery#' );
719 require_js( 'functions.js' ); // for rollovers AddEvent - TODO: change to jQuery691 require_js( 'functions.min.js' ); // for rollovers AddEvent - TODO: change to jQuery
720 require_js( 'rollovers.js' ); // TODO: change to jQuery692 require_js( 'rollovers.js' ); // @todo (0000): change to jQuery
721 // Superfish menus:693 // Superfish menus:
722 require_js( 'hoverintent.js' );694 require_js( 'hoverintent.js' );
723 require_js( 'superfish.js' );695 require_js( 'superfish.js' );
@@ -736,7 +708,6 @@
736708
737/**709/**
738 * T-Tag: Outputs the collected HTML HEAD lines.710 * T-Tag: Outputs the collected HTML HEAD lines.
739 *
740 * @see add_headline()711 * @see add_headline()
741 * @return string712 * @return string
742 */713 */
@@ -810,8 +781,8 @@
810781
811/**782/**
812 * T-Tag: Display links to previous and next posts in single post mode783 * T-Tag: Display links to previous and next posts in single post mode
813 *
814 * @uses ItemList2::prevnext_item_links()784 * @uses ItemList2::prevnext_item_links()
785 * @param array Associative array of parameters
815 */786 */
816function item_prevnext_links( $params = array() )787function item_prevnext_links( $params = array() )
817{788{
@@ -830,13 +801,13 @@
830 * <code>801 * <code>
831 * $params = array_merge( array(802 * $params = array_merge( array(
832 * 'block_start' => '<div class="action_messages">',803 * 'block_start' => '<div class="action_messages">',
833 * 'block_end' => '</div>',804 * 'block_end' => '</div>',
834 * ), $params );805 * ), $params );
835 * </code>806 * </code>
836 *
837 * @todo Tblue: Default values taken from Log::disp() ... this seems redundant807 * @todo Tblue: Default values taken from Log::disp() ... this seems redundant
838 * @uses Log::disp()808 * @uses Log::disp()
839 * @uses Log::display()809 * @uses Log::display()
810 * @param array Associative array of parameters
840 */811 */
841function messages( $params = array() )812function messages( $params = array() )
842{813{
@@ -844,7 +815,7 @@
844815
845 $params = array_merge( array(816 $params = array_merge( array(
846 'block_start' => '<div class="action_messages">',817 'block_start' => '<div class="action_messages">',
847 'block_end' => '</div>',818 'block_end' => '</div>',
848 ), $params );819 ), $params );
849820
850 $Messages->disp( $params['block_start'], $params['block_end'] );821 $Messages->disp( $params['block_start'], $params['block_end'] );
@@ -853,8 +824,8 @@
853824
854/**825/**
855 * T-Tag: Display links to previous and next posts in multi-post (or list) mode826 * T-Tag: Display links to previous and next posts in multi-post (or list) mode
856 *
857 * @uses ItemListLight::page_links()827 * @uses ItemListLight::page_links()
828 * @param array Associative array of parameters
858 */829 */
859function mainlist_page_links( $params = array() )830function mainlist_page_links( $params = array() )
860{831{
@@ -869,7 +840,6 @@
869840
870/**841/**
871 * T-Tag: Return an Item or NULL842 * T-Tag: Return an Item or NULL
872 *
873 * @uses ItemListLight::get_item()843 * @uses ItemListLight::get_item()
874 */844 */
875function & mainlist_get_item()845function & mainlist_get_item()
@@ -881,7 +851,8 @@
881 $Item = & $MainList->get_item();851 $Item = & $MainList->get_item();
882852
883 if( $Item && $Item->ID === $featured_displayed_item_ID )853 if( $Item && $Item->ID === $featured_displayed_item_ID )
884 { // This post was already displayed as a Featured post, let's skip it and get the next one:854 {
855 // This post was already displayed as a Featured post, let's skip it and get the next one:
885 $Item = & $MainList->get_item();856 $Item = & $MainList->get_item();
886 }857 }
887 }858 }
@@ -895,8 +866,8 @@
895866
896/**867/**
897 * T-Tag: Display a message if MainList is empty868 * T-Tag: Display a message if MainList is empty
898 *
899 * @uses Results::display_if_empty()869 * @uses Results::display_if_empty()
870 * @param array Associative array of parameters
900 */871 */
901function display_if_empty( $params = array() )872function display_if_empty( $params = array() )
902{873{
@@ -916,7 +887,7 @@
916 */887 */
917function star_rating( $stars, $class = 'middle' )888function star_rating( $stars, $class = 'middle' )
918{889{
919 if( is_null($stars) )890 if( is_null( $stars ) )
920 {891 {
921 return;892 return;
922 }893 }
@@ -925,15 +896,15 @@
925 {896 {
926 if( $i <= $stars )897 if( $i <= $stars )
927 {898 {
928 echo get_icon( 'star_on', 'imgtag', array( 'class'=>$class ) );899 echo get_icon( 'star_on', 'imgtag', array( 'class' => $class ) );
929 }900 }
930 elseif( $i-.5 <= $stars )901 elseif( $i-.5 <= $stars )
931 {902 {
932 echo get_icon( 'star_half', 'imgtag', array( 'class'=>$class ) );903 echo get_icon( 'star_half', 'imgtag', array( 'class' => $class ) );
933 }904 }
934 else905 else
935 {906 {
936 echo get_icon( 'star_off', 'imgtag', array( 'class'=>$class ) );907 echo get_icon( 'star_off', 'imgtag', array( 'class' => $class ) );
937 }908 }
938 }909 }
939}910}
940911
=== modified file 'qp_inc/_core/model/__core.install.php'
--- qp_inc/_core/model/__core.install.php 2013-02-28 16:40:18 +0000
+++ qp_inc/_core/model/__core.install.php 2013-03-05 23:36:23 +0000
@@ -64,86 +64,23 @@
64 UNIQUE KEY blog_urlname (blog_urlname)64 UNIQUE KEY blog_urlname (blog_urlname)
65 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),65 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
6666
67 'T_groups' => array( 'Creating table for Groups',67 'T_coll_group_perms' => array( 'Creating table for blog-group permissions',
68 "CREATE TABLE T_groups (68 "CREATE TABLE T_coll_group_perms (
69 grp_ID INT(11) NOT NULL auto_increment,69 bloggroup_blog_ID INT(11) unsigned NOT NULL default 0,
70 grp_name VARCHAR(50) NOT NULL default '',70 bloggroup_group_ID INT(11) unsigned NOT NULL default 0,
71 grp_perm_admin enum('none','hidden','visible') NOT NULL default 'visible',71 bloggroup_ismember TINYINT NOT NULL default 0,
72 grp_perm_blogs enum('user','viewall','editall') NOT NULL default 'user',72 bloggroup_perm_poststatuses set('published','deprecated','protected','private','draft','redirected') NOT NULL default '',
73 grp_perm_bypass_antispam TINYINT(1) NOT NULL DEFAULT 0,73 bloggroup_perm_edit ENUM('no','own','lt','le','all','redirected') NOT NULL default 'no',
74 grp_perm_xhtmlvalidation VARCHAR(10) NOT NULL default 'always',74 bloggroup_perm_delpost TINYINT NOT NULL default 0,
75 grp_perm_xhtmlvalidation_xmlrpc VARCHAR(10) NOT NULL default 'always',75 bloggroup_perm_comments TINYINT NOT NULL default 0,
76 grp_perm_xhtml_css_tweaks TINYINT(1) NOT NULL DEFAULT 0,76 bloggroup_perm_cats TINYINT NOT NULL default 0,
77 grp_perm_xhtml_iframes TINYINT(1) NOT NULL DEFAULT 0,77 bloggroup_perm_properties TINYINT NOT NULL default 0,
78 grp_perm_xhtml_javascript TINYINT(1) NOT NULL DEFAULT 0,78 bloggroup_perm_admin TINYINT NOT NULL default 0,
79 grp_perm_xhtml_objects TINYINT(1) NOT NULL DEFAULT 0,79 bloggroup_perm_media_upload TINYINT NOT NULL default 0,
80 grp_perm_stats enum('none','user','view','edit') NOT NULL default 'none',80 bloggroup_perm_media_browse TINYINT NOT NULL default 0,
81 grp_perm_spamblacklist enum('none','view','edit') NOT NULL default 'none',81 bloggroup_perm_media_change TINYINT NOT NULL default 0,
82 grp_perm_options enum('none','view','edit') NOT NULL default 'none',82 PRIMARY KEY bloggroup_pk (bloggroup_blog_ID,bloggroup_group_ID)
83 grp_perm_users enum('none','view','edit') NOT NULL default 'none',83 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
84 grp_perm_templates TINYINT NOT NULL DEFAULT 0,
85 grp_perm_files enum('none','view','add','edit','all') NOT NULL default 'none',
86 PRIMARY KEY grp_ID (grp_ID)
87 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
88
89 'T_settings' => array( 'Creating table for Settings',
90 "CREATE TABLE T_settings (
91 set_name VARCHAR( 30 ) NOT NULL ,
92 set_value VARCHAR( 255 ) NULL ,
93 PRIMARY KEY ( set_name )
94 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
95
96 'T_global__cache' => array( 'Creating table for Caches',
97 "CREATE TABLE T_global__cache (
98 cach_name VARCHAR( 30 ) NOT NULL ,
99 cach_cache MEDIUMBLOB NULL ,
100 PRIMARY KEY ( cach_name )
101 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
102
103 'T_users' => array( 'Creating table for Users',
104 "CREATE TABLE T_users (
105 user_ID INT(11) unsigned NOT NULL auto_increment,
106 user_login VARCHAR(20) NOT NULL,
107 user_pass CHAR(40) NOT NULL,
108 user_firstname VARCHAR(50) NULL,
109 user_lastname VARCHAR(50) NULL,
110 user_nickname VARCHAR(50) NULL,
111 user_email VARCHAR(255) NOT NULL,
112 user_url VARCHAR(255) NULL,
113 user_ip VARCHAR(15) NULL,
114 user_domain VARCHAR(200) NULL,
115 user_browser VARCHAR(200) NULL,
116 dateYMDhour datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
117 user_level int unsigned DEFAULT 0 NOT NULL,
118 user_locale VARCHAR(20) DEFAULT 'en-EU' NOT NULL,
119 user_idmode VARCHAR(20) NOT NULL DEFAULT 'login',
120 user_allow_msgform TINYINT NOT NULL DEFAULT '1',
121 user_notify tinyint(1) NOT NULL default 1,
122 user_showonline tinyint(1) NOT NULL default 1,
123 user_grp_ID INT(4) NOT NULL default 1,
124 user_validated tinyint(1) NOT NULL DEFAULT 0,
125 PRIMARY KEY user_ID (user_ID),
126 UNIQUE user_login (user_login),
127 KEY user_grp_ID (user_grp_ID)
128 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
129
130 'T_templates__template' => array( 'Creating table for installed templates',
131 "CREATE TABLE T_templates__template (
132 template_ID INT(10) unsigned NOT NULL auto_increment,
133 template_name VARCHAR(32) NOT NULL,
134 template_type enum('xhtml','feed','other') NOT NULL default 'xhtml',
135 template_folder VARCHAR(32) NOT NULL,
136 PRIMARY KEY template_ID (template_ID),
137 UNIQUE template_folder( template_folder ),
138 KEY template_name( template_name )
139 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
140
141 'T_templates__container' => array( 'Creating table for template containers',
142 "CREATE TABLE T_templates__container (
143 sco_template_ID INT(10) unsigned NOT NULL,
144 sco_name VARCHAR(40) NOT NULL,
145 PRIMARY KEY (sco_template_ID, sco_name)
146 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
14784
148 'T_coll_settings' => array( 'Creating collection settings table',85 'T_coll_settings' => array( 'Creating collection settings table',
149 "CREATE TABLE T_coll_settings (86 "CREATE TABLE T_coll_settings (
@@ -153,18 +90,22 @@
153 PRIMARY KEY ( cset_coll_ID, cset_name )90 PRIMARY KEY ( cset_coll_ID, cset_name )
154 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),91 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
15592
156 'T_widget' => array( 'Creating components table',93 'T_coll_user_perms' => array( 'Creating table for Blog-User permissions',
157 "CREATE TABLE T_widget (94 "CREATE TABLE T_coll_user_perms (
158 wi_ID INT(10) UNSIGNED auto_increment,95 bloguser_blog_ID INT(11) unsigned NOT NULL default 0,
159 wi_coll_ID INT(11) UNSIGNED NOT NULL,96 bloguser_user_ID INT(11) unsigned NOT NULL default 0,
160 wi_sco_name VARCHAR( 40 ) NOT NULL,97 bloguser_ismember TINYINT NOT NULL default 0,
161 wi_order INT(10) NOT NULL,98 bloguser_perm_poststatuses set('published','deprecated','protected','private','draft','redirected') NOT NULL default '',
162 wi_enabled TINYINT(1) NOT NULL DEFAULT 1,99 bloguser_perm_edit ENUM('no','own','lt','le','all','redirected') NOT NULL default 'no',
163 wi_type ENUM( 'widget', 'plugin' ) NOT NULL DEFAULT 'widget',100 bloguser_perm_delpost TINYINT NOT NULL default 0,
164 wi_code VARCHAR(32) NOT NULL,101 bloguser_perm_comments TINYINT NOT NULL default 0,
165 wi_params TEXT NULL,102 bloguser_perm_cats TINYINT NOT NULL default 0,
166 PRIMARY KEY ( wi_ID ),103 bloguser_perm_properties TINYINT NOT NULL default 0,
167 UNIQUE wi_order( wi_coll_ID, wi_sco_name, wi_order )104 bloguser_perm_admin TINYINT NOT NULL default 0,
105 bloguser_perm_media_upload TINYINT NOT NULL default 0,
106 bloguser_perm_media_browse TINYINT NOT NULL default 0,
107 bloguser_perm_media_change TINYINT NOT NULL default 0,
108 PRIMARY KEY bloguser_pk (bloguser_blog_ID,bloguser_user_ID)
168 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),109 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
169110
170 'T_categories' => array( 'Creating table for Categories',111 'T_categories' => array( 'Creating table for Categories',
@@ -183,6 +124,99 @@
183 KEY cat_order (cat_order)124 KEY cat_order (cat_order)
184 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),125 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
185126
127 'T_comments' => array( 'Creating table for Comments',
128 "CREATE TABLE T_comments (
129 comment_ID INT(11) unsigned NOT NULL auto_increment,
130 comment_post_ID INT(11) unsigned NOT NULL default '0',
131 comment_type ENUM('comment','linkback','trackback') NOT NULL default 'comment',
132 comment_status ENUM('published','deprecated','protected','private','draft','redirected') DEFAULT 'published' NOT NULL,
133 comment_author_ID INT unsigned NULL default NULL,
134 comment_author VARCHAR(100) NULL,
135 comment_author_email VARCHAR(255) NULL,
136 comment_author_url VARCHAR(255) NULL,
137 comment_author_IP VARCHAR(23) NOT NULL default '',
138 comment_date DATETIME NOT NULL DEFAULT '2000-01-01 00:00:00',
139 comment_content text NOT NULL,
140 comment_rating TINYINT(1) NULL DEFAULT NULL,
141 comment_featured TINYINT(1) NOT NULL DEFAULT 0,
142 comment_nofollow TINYINT(1) NOT NULL DEFAULT 1,
143 comment_karma INT(11) NOT NULL DEFAULT 0,
144 comment_spam_karma TINYINT NULL,
145 comment_allow_msgform TINYINT NOT NULL DEFAULT 0,
146 PRIMARY KEY comment_ID (comment_ID),
147 KEY comment_post_ID (comment_post_ID),
148 KEY comment_date (comment_date),
149 KEY comment_type (comment_type)
150 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
151
152 'T_cron__log' => array( 'Creating cron tasks table',
153 "CREATE TABLE T_cron__log(
154 clog_ctsk_ID INT(10) unsigned not null,
155 clog_realstart_datetime DATETIME not null DEFAULT '2000-01-01 00:00:00',
156 clog_realstop_datetime DATETIME,
157 clog_status ENUM('started','finished','error','timeout') not null default 'started',
158 clog_messages text,
159 PRIMARY KEY ( clog_ctsk_ID )
160 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
161
162 'T_cron__task' => array( 'Creating cron tasks table',
163 "CREATE TABLE T_cron__task(
164 ctsk_ID INT(10) unsigned not null AUTO_INCREMENT,
165 ctsk_start_datetime DATETIME not null DEFAULT '2000-01-01 00:00:00',
166 ctsk_repeat_after INT(10) unsigned,
167 ctsk_name VARCHAR(50) not null,
168 ctsk_controller VARCHAR(50) not null,
169 ctsk_params text,
170 PRIMARY KEY ( ctsk_ID )
171 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
172
173 'T_files' => array( 'Creating table for File Meta Data',
174 "CREATE TABLE T_files (
175 file_ID INT(11) unsigned not null AUTO_INCREMENT,
176 file_root_type ENUM('absolute','user','collection','shared','templates') not null default 'absolute',
177 file_root_ID INT(11) unsigned not null default 0,
178 file_path VARCHAR(255) not null default '',
179 file_title VARCHAR(255),
180 file_alt VARCHAR(255),
181 file_desc text,
182 PRIMARY KEY ( file_ID ),
183 unique file (file_root_type, file_root_ID, file_path)
184 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
185
186 'T_filetypes' => array( 'Creating table for file types',
187 "CREATE TABLE T_filetypes (
188 ftyp_ID INT(11) unsigned NOT NULL auto_increment,
189 ftyp_extensions VARCHAR(30) NOT NULL,
190 ftyp_name VARCHAR(30) NOT NULL,
191 ftyp_mimetype VARCHAR(50) NOT NULL,
192 ftyp_icon VARCHAR(20) default NULL,
193 ftyp_viewtype VARCHAR(10) NOT NULL,
194 ftyp_allowed TINYINT(1) NOT NULL default 0,
195 PRIMARY KEY ( ftyp_ID )
196 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
197
198 'T_groups' => array( 'Creating table for Groups',
199 "CREATE TABLE T_groups (
200 grp_ID INT(11) NOT NULL auto_increment,
201 grp_name VARCHAR(50) NOT NULL default '',
202 grp_perm_admin ENUM('none','hidden','visible') NOT NULL default 'visible',
203 grp_perm_blogs ENUM('user','viewall','editall') NOT NULL default 'user',
204 grp_perm_bypass_antispam TINYINT(1) NOT NULL DEFAULT 0,
205 grp_perm_xhtmlvalidation VARCHAR(10) NOT NULL default 'always',
206 grp_perm_xhtmlvalidation_xmlrpc VARCHAR(10) NOT NULL default 'always',
207 grp_perm_xhtml_css_tweaks TINYINT(1) NOT NULL DEFAULT 0,
208 grp_perm_xhtml_iframes TINYINT(1) NOT NULL DEFAULT 0,
209 grp_perm_xhtml_javascript TINYINT(1) NOT NULL DEFAULT 0,
210 grp_perm_xhtml_objects TINYINT(1) NOT NULL DEFAULT 0,
211 grp_perm_stats ENUM('none','user','view','edit') NOT NULL default 'none',
212 grp_perm_spamblacklist ENUM('none','view','edit') NOT NULL default 'none',
213 grp_perm_options ENUM('none','view','edit') NOT NULL default 'none',
214 grp_perm_users ENUM('none','view','edit') NOT NULL default 'none',
215 grp_perm_templates TINYINT NOT NULL DEFAULT 0,
216 grp_perm_files ENUM('none','view','add','edit','all') NOT NULL default 'none',
217 PRIMARY KEY grp_ID (grp_ID)
218 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
219
186 'T_items__item' => array( 'Creating table for Posts',220 'T_items__item' => array( 'Creating table for Posts',
187 "CREATE TABLE T_items__item (221 "CREATE TABLE T_items__item (
188 post_ID INT(11) unsigned NOT NULL auto_increment,222 post_ID INT(11) unsigned NOT NULL auto_increment,
@@ -191,15 +225,15 @@
191 post_lastedit_user_ID INT(11) unsigned NULL,225 post_lastedit_user_ID INT(11) unsigned NULL,
192 post_assigned_user_ID INT(11) unsigned NULL,226 post_assigned_user_ID INT(11) unsigned NULL,
193 post_datestart DATETIME NOT NULL DEFAULT '2000-01-01 00:00:00',227 post_datestart DATETIME NOT NULL DEFAULT '2000-01-01 00:00:00',
194 post_datedeadline datetime NULL,228 post_datedeadline DATETIME NULL,
195 post_datecreated datetime NULL,229 post_datecreated DATETIME NULL,
196 post_datemodified DATETIME NOT NULL DEFAULT '2000-01-01 00:00:00',230 post_datemodified DATETIME NOT NULL DEFAULT '2000-01-01 00:00:00',
197 post_status enum('published','deprecated','protected','private','draft','redirected') NOT NULL default 'published',231 post_status ENUM('published','deprecated','protected','private','draft','redirected') NOT NULL default 'published',
198 post_pst_ID INT(11) unsigned NULL,232 post_pst_ID INT(11) unsigned NULL,
199 post_ptyp_ID INT(10) unsigned NOT NULL DEFAULT 1,233 post_ptyp_ID INT(10) unsigned NOT NULL DEFAULT 1,
200 post_locale VARCHAR(20) NOT NULL DEFAULT 'en-EU',234 post_locale VARCHAR(20) NOT NULL DEFAULT 'en-EU',
201 post_content MEDIUMTEXT NULL,235 post_content MEDIUMTEXT NULL,
202 post_excerpt text NULL,236 post_excerpt TEXT NULL,
203 post_title text NOT NULL,237 post_title text NOT NULL,
204 post_urltitle VARCHAR(210) NULL DEFAULT NULL,238 post_urltitle VARCHAR(210) NULL DEFAULT NULL,
205 post_titletag VARCHAR(255) NULL DEFAULT NULL,239 post_titletag VARCHAR(255) NULL DEFAULT NULL,
@@ -215,7 +249,7 @@
215 post_commentsexpire DATETIME DEFAULT NULL,249 post_commentsexpire DATETIME DEFAULT NULL,
216 post_renderers TEXT NOT NULL,250 post_renderers TEXT NOT NULL,
217 post_priority INT(11) unsigned null COMMENT 'Task priority in workflow',251 post_priority INT(11) unsigned null COMMENT 'Task priority in workflow',
218 post_featured tinyint(1) NOT NULL DEFAULT 0,252 post_featured TINYINT(1) NOT NULL DEFAULT 0,
219 post_order DOUBLE NULL,253 post_order DOUBLE NULL,
220 post_editor_code VARCHAR(32) NULL COMMENT 'Plugin code of the editor used to edit this post',254 post_editor_code VARCHAR(32) NULL COMMENT 'Plugin code of the editor used to edit this post',
221 PRIMARY KEY post_ID( post_ID ),255 PRIMARY KEY post_ID( post_ID ),
@@ -239,54 +273,6 @@
239 UNIQUE catpost ( postcat_cat_ID, postcat_post_ID )273 UNIQUE catpost ( postcat_cat_ID, postcat_post_ID )
240 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),274 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
241275
242 'T_comments' => array( 'Creating table for Comments',
243 "CREATE TABLE T_comments (
244 comment_ID INT(11) unsigned NOT NULL auto_increment,
245 comment_post_ID INT(11) unsigned NOT NULL default '0',
246 comment_type enum('comment','linkback','trackback') NOT NULL default 'comment',
247 comment_status ENUM('published','deprecated','protected','private','draft','redirected') DEFAULT 'published' NOT NULL,
248 comment_author_ID int unsigned NULL default NULL,
249 comment_author VARCHAR(100) NULL,
250 comment_author_email VARCHAR(255) NULL,
251 comment_author_url VARCHAR(255) NULL,
252 comment_author_IP VARCHAR(23) NOT NULL default '',
253 comment_date datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
254 comment_content text NOT NULL,
255 comment_rating TINYINT(1) NULL DEFAULT NULL,
256 comment_featured TINYINT(1) NOT NULL DEFAULT 0,
257 comment_nofollow TINYINT(1) NOT NULL DEFAULT 1,
258 comment_karma INT(11) NOT NULL DEFAULT 0,
259 comment_spam_karma TINYINT NULL,
260 comment_allow_msgform TINYINT NOT NULL DEFAULT 0,
261 PRIMARY KEY comment_ID (comment_ID),
262 KEY comment_post_ID (comment_post_ID),
263 KEY comment_date (comment_date),
264 KEY comment_type (comment_type)
265 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
266
267 'T_locales' => array( 'Creating table for Locales',
268 "CREATE TABLE T_locales (
269 loc_locale VARCHAR(20) NOT NULL default '',
270 loc_charset VARCHAR(15) NOT NULL default 'iso-8859-1',
271 loc_datefmt VARCHAR(20) NOT NULL default 'y-m-d',
272 loc_timefmt VARCHAR(20) NOT NULL default 'H:i:s',
273 loc_startofweek TINYINT UNSIGNED NOT NULL DEFAULT 1,
274 loc_name VARCHAR(40) NOT NULL default '',
275 loc_messages VARCHAR(20) NOT NULL default '',
276 loc_priority tinyint(4) UNSIGNED NOT NULL default '0',
277 loc_enabled tinyint(4) NOT NULL default '1',
278 PRIMARY KEY loc_locale( loc_locale )
279 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset COMMENT='saves available locales'
280 " ),
281
282 'T_usersettings' => array( 'Creating user settings table',
283 "CREATE TABLE T_usersettings (
284 uset_user_ID INT(11) UNSIGNED NOT NULL,
285 uset_name VARCHAR( 30 ) NOT NULL,
286 uset_value VARCHAR( 255 ) NULL,
287 PRIMARY KEY ( uset_user_ID, uset_name )
288 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
289
290 'T_items__prerendering' => array( 'Creating item prerendering cache table',276 'T_items__prerendering' => array( 'Creating item prerendering cache table',
291 "CREATE TABLE T_items__prerendering(277 "CREATE TABLE T_items__prerendering(
292 itpr_itm_ID INT(11) UNSIGNED NOT NULL,278 itpr_itm_ID INT(11) UNSIGNED NOT NULL,
@@ -294,106 +280,40 @@
294 itpr_renderers TEXT NOT NULL,280 itpr_renderers TEXT NOT NULL,
295 itpr_content_prerendered MEDIUMTEXT NULL,281 itpr_content_prerendered MEDIUMTEXT NULL,
296 itpr_datemodified TIMESTAMP NOT NULL,282 itpr_datemodified TIMESTAMP NOT NULL,
297 PRIMARY KEY (itpr_itm_ID, itpr_format)283 PRIMARY KEY ( itpr_itm_ID, itpr_format )
298 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),284 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
299285
300 'T_items__version' => array( 'Creating item versions table',
301 "CREATE TABLE T_items__version (
302 iver_itm_ID INT UNSIGNED NOT NULL ,
303 iver_edit_user_ID INT UNSIGNED NULL ,
304 iver_edit_datetime DATETIME NOT NULL ,
305 iver_status ENUM('published','deprecated','protected','private','draft','redirected') NULL ,
306 iver_title TEXT NULL ,
307 iver_content MEDIUMTEXT NULL ,
308 INDEX iver_itm_ID ( iver_itm_ID )
309 ) ENGINE = innodb ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
310
311 'T_items__status' => array( 'Creating table for Post Statuses',286 'T_items__status' => array( 'Creating table for Post Statuses',
312 "CREATE TABLE T_items__status (287 "CREATE TABLE T_items__status (
313 pst_ID INT(11) unsigned not null AUTO_INCREMENT,288 pst_ID INT(11) unsigned not null AUTO_INCREMENT,
314 pst_name VARCHAR(30) not null,289 pst_name VARCHAR(30) not null,
315 primary key ( pst_ID )290 PRIMARY KEY ( pst_ID )
316 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
317
318 'T_items__type' => array( 'Creating table for Post Types',
319 "CREATE TABLE T_items__type (
320 ptyp_ID INT(11) unsigned not null AUTO_INCREMENT,
321 ptyp_name VARCHAR(30) not null,
322 primary key (ptyp_ID)
323 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
324
325 'T_items__tag' => array( 'Creating table for Tags',
326 "CREATE TABLE T_items__tag (
327 tag_ID INT(11) unsigned not null AUTO_INCREMENT,
328 tag_name VARCHAR(50) not null,
329 primary key (tag_ID),
330 UNIQUE tag_name( tag_name )
331 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),291 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
332292
333 'T_items__itemtag' => array( 'Creating table for Post-to-Tag relationships',293 'T_items__itemtag' => array( 'Creating table for Post-to-Tag relationships',
334 "CREATE TABLE T_items__itemtag (294 "CREATE TABLE T_items__itemtag (
335 itag_itm_ID INT(11) unsigned NOT NULL,295 itag_itm_ID INT(11) unsigned NOT NULL,
336 itag_tag_ID INT(11) unsigned NOT NULL,296 itag_tag_ID INT(11) unsigned NOT NULL,
337 PRIMARY KEY (itag_itm_ID, itag_tag_ID),297 PRIMARY KEY ( itag_itm_ID, itag_tag_ID ),
338 UNIQUE tagitem ( itag_tag_ID, itag_itm_ID )298 UNIQUE tagitem ( itag_tag_ID, itag_itm_ID )
339 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),299 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
340300
341 'T_files' => array( 'Creating table for File Meta Data',301 'T_items__type' => array( 'Creating table for Post Types',
342 "CREATE TABLE T_files (302 "CREATE TABLE T_items__type (
343 file_ID INT(11) unsigned not null AUTO_INCREMENT,303 ptyp_ID INT(11) unsigned not null AUTO_INCREMENT,
344 file_root_type enum('absolute','user','collection','shared','templates') not null default 'absolute',304 ptyp_name VARCHAR(30) not null,
345 file_root_ID INT(11) unsigned not null default 0,305 PRIMARY KEY ( ptyp_ID )
346 file_path VARCHAR(255) not null default '',306 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
347 file_title VARCHAR(255),307
348 file_alt VARCHAR(255),308 'T_items__version' => array( 'Creating item versions table',
349 file_desc text,309 "CREATE TABLE T_items__version (
350 primary key (file_ID),310 iver_itm_ID INT UNSIGNED NOT NULL,
351 unique file (file_root_type, file_root_ID, file_path)311 iver_edit_user_ID INT UNSIGNED NULL,
352 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),312 iver_edit_datetime DATETIME NOT NULL,
353313 iver_status ENUM('published','deprecated','protected','private','draft','redirected') NULL,
354 'T_subscriptions' => array( 'Creating table for subscriptions',314 iver_title TEXT NULL,
355 "CREATE TABLE T_subscriptions (315 iver_content MEDIUMTEXT NULL,
356 sub_coll_ID INT(11) unsigned not null,316 INDEX iver_itm_ID ( iver_itm_ID )
357 sub_user_ID INT(11) unsigned not null,
358 sub_items tinyint(1) not null,
359 sub_comments tinyint(1) not null,
360 primary key (sub_coll_ID, sub_user_ID)
361 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
362
363 'T_coll_user_perms' => array( 'Creating table for Blog-User permissions',
364 "CREATE TABLE T_coll_user_perms (
365 bloguser_blog_ID INT(11) unsigned NOT NULL default 0,
366 bloguser_user_ID INT(11) unsigned NOT NULL default 0,
367 bloguser_ismember tinyint NOT NULL default 0,
368 bloguser_perm_poststatuses set('published','deprecated','protected','private','draft','redirected') NOT NULL default '',
369 bloguser_perm_edit ENUM('no','own','lt','le','all','redirected') NOT NULL default 'no',
370 bloguser_perm_delpost tinyint NOT NULL default 0,
371 bloguser_perm_comments tinyint NOT NULL default 0,
372 bloguser_perm_cats tinyint NOT NULL default 0,
373 bloguser_perm_properties tinyint NOT NULL default 0,
374 bloguser_perm_admin tinyint NOT NULL default 0,
375 bloguser_perm_media_upload tinyint NOT NULL default 0,
376 bloguser_perm_media_browse tinyint NOT NULL default 0,
377 bloguser_perm_media_change tinyint NOT NULL default 0,
378 PRIMARY KEY bloguser_pk (bloguser_blog_ID,bloguser_user_ID)
379 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
380
381 'T_coll_group_perms' => array( 'Creating table for blog-group permissions',
382 "CREATE TABLE T_coll_group_perms (
383 bloggroup_blog_ID INT(11) unsigned NOT NULL default 0,
384 bloggroup_group_ID INT(11) unsigned NOT NULL default 0,
385 bloggroup_ismember tinyint NOT NULL default 0,
386 bloggroup_perm_poststatuses set('published','deprecated','protected','private','draft','redirected') NOT NULL default '',
387 bloggroup_perm_edit ENUM('no','own','lt','le','all','redirected') NOT NULL default 'no',
388 bloggroup_perm_delpost tinyint NOT NULL default 0,
389 bloggroup_perm_comments tinyint NOT NULL default 0,
390 bloggroup_perm_cats tinyint NOT NULL default 0,
391 bloggroup_perm_properties tinyint NOT NULL default 0,
392 bloggroup_perm_admin tinyint NOT NULL default 0,
393 bloggroup_perm_media_upload tinyint NOT NULL default 0,
394 bloggroup_perm_media_browse tinyint NOT NULL default 0,
395 bloggroup_perm_media_change tinyint NOT NULL default 0,
396 PRIMARY KEY bloggroup_pk (bloggroup_blog_ID,bloggroup_group_ID)
397 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),317 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
398318
399 'T_links' => array( 'Creating table for Post Links',319 'T_links' => array( 'Creating table for Post Links',
@@ -409,23 +329,26 @@
409 link_ltype_ID INT(11) unsigned NOT NULL default 1,329 link_ltype_ID INT(11) unsigned NOT NULL default 1,
410 link_external_url VARCHAR(255) NULL,330 link_external_url VARCHAR(255) NULL,
411 link_title TEXT NULL,331 link_title TEXT NULL,
412 PRIMARY KEY (link_ID),332 PRIMARY KEY ( link_ID ),
413 INDEX link_itm_ID( link_itm_ID ),333 INDEX link_itm_ID( link_itm_ID ),
414 INDEX link_dest_itm_ID (link_dest_itm_ID),334 INDEX link_dest_itm_ID (link_dest_itm_ID),
415 INDEX link_file_ID (link_file_ID)335 INDEX link_file_ID (link_file_ID)
416 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),336 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
417337
418 'T_filetypes' => array( 'Creating table for file types',338 'T_locales' => array( 'Creating table for Locales',
419 "CREATE TABLE T_filetypes (339 "CREATE TABLE T_locales (
420 ftyp_ID INT(11) unsigned NOT NULL auto_increment,340 loc_locale VARCHAR(20) NOT NULL default '',
421 ftyp_extensions VARCHAR(30) NOT NULL,341 loc_charset VARCHAR(15) NOT NULL default 'iso-8859-1',
422 ftyp_name VARCHAR(30) NOT NULL,342 loc_datefmt VARCHAR(20) NOT NULL default 'y-m-d',
423 ftyp_mimetype VARCHAR(50) NOT NULL,343 loc_timefmt VARCHAR(20) NOT NULL default 'H:i:s',
424 ftyp_icon VARCHAR(20) default NULL,344 loc_startofweek TINYINT UNSIGNED NOT NULL DEFAULT 1,
425 ftyp_viewtype VARCHAR(10) NOT NULL,345 loc_name VARCHAR(40) NOT NULL default '',
426 ftyp_allowed tinyint(1) NOT NULL default 0,346 loc_messages VARCHAR(20) NOT NULL default '',
427 PRIMARY KEY (ftyp_ID)347 loc_priority TINYINT(4) UNSIGNED NOT NULL default '0',
428 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),348 loc_enabled TINYINT(4) NOT NULL default '1',
349 PRIMARY KEY loc_locale( loc_locale )
350 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset COMMENT='saves available locales'
351 " ),
429352
430 'T_plugins' => array( 'Creating plugins table',353 'T_plugins' => array( 'Creating plugins table',
431 "CREATE TABLE T_plugins (354 "CREATE TABLE T_plugins (
@@ -449,7 +372,7 @@
449 pevt_plug_ID INT(11) UNSIGNED NOT NULL,372 pevt_plug_ID INT(11) UNSIGNED NOT NULL,
450 pevt_event VARCHAR(40) NOT NULL,373 pevt_event VARCHAR(40) NOT NULL,
451 pevt_enabled TINYINT NOT NULL DEFAULT 1,374 pevt_enabled TINYINT NOT NULL DEFAULT 1,
452 PRIMARY KEY( pevt_plug_ID, pevt_event )375 PRIMARY KEY ( pevt_plug_ID, pevt_event )
453 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),376 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
454377
455 'T_pluginsettings' => array( 'Creating plugin settings table',378 'T_pluginsettings' => array( 'Creating plugin settings table',
@@ -460,6 +383,115 @@
460 PRIMARY KEY ( pset_plug_ID, pset_name )383 PRIMARY KEY ( pset_plug_ID, pset_name )
461 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),384 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
462385
386 'T_pluginusersettings' => array( 'Creating plugin user settings table',
387 "CREATE TABLE T_pluginusersettings (
388 puset_plug_ID INT(11) UNSIGNED NOT NULL,
389 puset_user_ID INT(11) UNSIGNED NOT NULL,
390 puset_name VARCHAR( 30 ) NOT NULL,
391 puset_value TEXT NULL,
392 PRIMARY KEY ( puset_plug_ID, puset_user_ID, puset_name )
393 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
394
395 'T_settings' => array( 'Creating table for Settings',
396 "CREATE TABLE T_settings (
397 set_name VARCHAR( 30 ) NOT NULL,
398 set_value VARCHAR( 255 ) NULL,
399 PRIMARY KEY ( set_name )
400 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
401
402 'T_subscriptions' => array( 'Creating table for subscriptions',
403 "CREATE TABLE T_subscriptions (
404 sub_coll_ID INT(11) unsigned not null,
405 sub_user_ID INT(11) unsigned not null,
406 sub_items TINYINT(1) not null,
407 sub_comments TINYINT(1) not null,
408 PRIMARY KEY ( sub_coll_ID, sub_user_ID )
409 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
410
411 'T_items__tag' => array( 'Creating table for Tags',
412 "CREATE TABLE T_items__tag (
413 tag_ID INT(11) unsigned not null AUTO_INCREMENT,
414 tag_name VARCHAR(50) not null,
415 PRIMARY KEY ( tag_ID ),
416 UNIQUE tag_name( tag_name )
417 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
418
419 'T_templates__template' => array( 'Creating table for installed templates',
420 "CREATE TABLE T_templates__template (
421 template_ID INT(10) unsigned NOT NULL auto_increment,
422 template_name VARCHAR(32) NOT NULL,
423 template_type ENUM('xhtml','feed','other') NOT NULL default 'xhtml',
424 template_folder VARCHAR(32) NOT NULL,
425 PRIMARY KEY template_ID (template_ID),
426 UNIQUE template_folder( template_folder ),
427 KEY template_name( template_name )
428 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
429
430 'T_templates__container' => array( 'Creating table for template containers',
431 "CREATE TABLE T_templates__container (
432 sco_template_ID INT(10) unsigned NOT NULL,
433 sco_name VARCHAR(40) NOT NULL,
434 PRIMARY KEY ( sco_template_ID, sco_name )
435 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
436
437 'T_users' => array( 'Creating users table',
438 "CREATE TABLE T_users (
439 user_ID INT(11) unsigned NOT NULL auto_increment,
440 user_login VARCHAR(20) NOT NULL,
441 user_pass CHAR(40) NOT NULL,
442 user_firstname VARCHAR(50) NULL,
443 user_lastname VARCHAR(50) NULL,
444 user_nickname VARCHAR(50) NULL,
445 user_email VARCHAR(255) NOT NULL,
446 user_url VARCHAR(255) NULL,
447 user_ip VARCHAR(15) NULL,
448 user_domain VARCHAR(200) NULL,
449 user_browser VARCHAR(200) NULL,
450 dateYMDhour DATETIME NOT NULL DEFAULT '2000-01-01 00:00:00',
451 user_level int unsigned DEFAULT 0 NOT NULL,
452 user_locale VARCHAR(20) DEFAULT 'en-EU' NOT NULL,
453 user_idmode VARCHAR(20) NOT NULL DEFAULT 'login',
454 user_allow_msgform TINYINT NOT NULL DEFAULT '1',
455 user_notify TINYINT(1) NOT NULL default 1,
456 user_showonline TINYINT(1) NOT NULL default 1,
457 user_grp_ID INT(4) NOT NULL default 1,
458 user_validated TINYINT(1) NOT NULL DEFAULT 0,
459 user_avatar_ID INT(10) NULL,
460 user_biography TEXT NULL DEFAULT NULL,
461 PRIMARY KEY user_ID (user_ID),
462 UNIQUE user_login (user_login),
463 KEY user_grp_ID (user_grp_ID)
464 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
465
466 'T_global__cache' => array( 'Creating table for Caches',
467 "CREATE TABLE T_global__cache (
468 cach_name VARCHAR( 30 ) NOT NULL,
469 cach_cache MEDIUMBLOB NULL,
470 PRIMARY KEY ( cach_name )
471 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
472
473 'T_widget' => array( 'Creating components table',
474 "CREATE TABLE T_widget (
475 wi_ID INT(10) UNSIGNED auto_increment,
476 wi_coll_ID INT(11) UNSIGNED NOT NULL,
477 wi_sco_name VARCHAR( 40 ) NOT NULL,
478 wi_order INT(10) NOT NULL,
479 wi_enabled TINYINT(1) NOT NULL DEFAULT 1,
480 wi_type ENUM( 'widget', 'plugin' ) NOT NULL DEFAULT 'widget',
481 wi_code VARCHAR(32) NOT NULL,
482 wi_params TEXT NULL,
483 PRIMARY KEY ( wi_ID ),
484 UNIQUE wi_order( wi_coll_ID, wi_sco_name, wi_order )
485 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
486
487 'T_usersettings' => array( 'Creating user settings table',
488 "CREATE TABLE T_usersettings (
489 uset_user_ID INT(11) UNSIGNED NOT NULL,
490 uset_name VARCHAR( 30 ) NOT NULL,
491 uset_value VARCHAR( 255 ) NULL,
492 PRIMARY KEY ( uset_user_ID, uset_name )
493 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
494
463 /**495 /**
464 * This table holds info about fields a plugin might want to access and496 * This table holds info about fields a plugin might want to access and
465 * use. The only time it gets called is on a plugin's settings page497 * use. The only time it gets called is on a plugin's settings page
@@ -472,7 +504,7 @@
472 psf_type VARCHAR(255) NOT NULL, -- probably only 'text', maybe 'checkbox', 'select' is crazy talk!504 psf_type VARCHAR(255) NOT NULL, -- probably only 'text', maybe 'checkbox', 'select' is crazy talk!
473 psf_note VARCHAR(255) NOT NULL,505 psf_note VARCHAR(255) NOT NULL,
474 psf_validate VARCHAR(255) NOT NULL, -- make sure a url is a url ... for example506 psf_validate VARCHAR(255) NOT NULL, -- make sure a url is a url ... for example
475 PRIMARY KEY (psf_fieldname)507 PRIMARY KEY ( psf_fieldname )
476 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),508 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
477509
478 /**510 /**
@@ -487,39 +519,9 @@
487 psv_user_ID INT(10) unsigned NOT NULL,519 psv_user_ID INT(10) unsigned NOT NULL,
488 psv_psf_fieldname VARCHAR(32) NOT NULL,520 psv_psf_fieldname VARCHAR(32) NOT NULL,
489 psv_userfieldvalue VARCHAR(255) NOT NULL,521 psv_userfieldvalue VARCHAR(255) NOT NULL,
490 PRIMARY KEY (psv_ID)522 PRIMARY KEY ( psv_ID )
491 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),523 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
492524
493 'T_pluginusersettings' => array( 'Creating plugin user settings table',
494 "CREATE TABLE T_pluginusersettings (
495 puset_plug_ID INT(11) UNSIGNED NOT NULL,
496 puset_user_ID INT(11) UNSIGNED NOT NULL,
497 puset_name VARCHAR( 30 ) NOT NULL,
498 puset_value TEXT NULL,
499 PRIMARY KEY ( puset_plug_ID, puset_user_ID, puset_name )
500 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
501
502 'T_cron__task' => array( 'Creating cron tasks table',
503 "CREATE TABLE T_cron__task(
504 ctsk_ID INT(10) unsigned not null AUTO_INCREMENT,
505 ctsk_start_datetime datetime not null DEFAULT '2000-01-01 00:00:00',
506 ctsk_repeat_after INT(10) unsigned,
507 ctsk_name VARCHAR(50) not null,
508 ctsk_controller VARCHAR(50) not null,
509 ctsk_params text,
510 PRIMARY KEY (ctsk_ID)
511 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
512
513 'T_cron__log' => array( 'Creating cron tasks table',
514 "CREATE TABLE T_cron__log(
515 clog_ctsk_ID INT(10) unsigned not null,
516 clog_realstart_datetime datetime not null DEFAULT '2000-01-01 00:00:00',
517 clog_realstop_datetime datetime,
518 clog_status enum('started','finished','error','timeout') not null default 'started',
519 clog_messages text,
520 PRIMARY KEY (clog_ctsk_ID)
521 ) ENGINE = innodb DEFAULT CHARSET = $db_storage_charset" ),
522);525);
523526
524
525?>527?>
526528
=== modified file 'qp_inc/files/files.ctrl.php'
--- qp_inc/files/files.ctrl.php 2011-08-19 16:20:19 +0000
+++ qp_inc/files/files.ctrl.php 2013-03-05 23:36:23 +0000
@@ -1,63 +1,32 @@
1<?php1<?php
2/**2/**
3 * This file implements the UI controller for file management.3 * $ctrl_mappings: 'files' || Files -> browse (not upload)
4 *4 *
5 * NOTE: $fm_mode is used for modes. Modes stay visible when browsing to a different location.5 * NOTE: $fm_mode is used for modes. Modes stay visible when browsing to a different
6 * Examples of modes: link item, copy file.6 * location.
7 * - Examples of modes: link item, copy file.
7 * Actions disappear if you browse to a different location.8 * Actions disappear if you browse to a different location.
8 * Examples of actions: file properties, file edit.9 * - Examples of actions: file properties, file edit.
9 *10 *
10 * fp>> Movr/copy should not be a mode (too geeky). All we need is a dir selection tree inside of upload and move.11 * @todo (1111): why does upload have it's own controller?
11 *12 * @uses Zip_Archive
12 * This file is part of Quam Plures - {@link http://quamplures.net/}13 * @author {@link http://wonderwinds.com/ Ed Bennett}
13 * See also {@link https://launchpad.net/quam-plures}.14 * @author {@link http://progidistri.com/ PROGIDISTRI}
14 *15 * @author {@link http://daniel.hahler.de/ Daniel HAHLER}
15 * @copyright (c) 2009 - 2011 by the Quam Plures developers - {@link http://quamplures.net/}16 * @author {@link http://fplanque.net/ Francois PLANQUE}
16 * @copyright (c)2003-2009 by Francois PLANQUE - {@link http://fplanque.net/}17 * @copyright (c) 2009 by {@link http://quamplures.net/ the Quam Plures project}
17 * Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.18 * @license http://www.gnu.org/licenses/gpl.txt GNU General Public License v3
18 * Parts of this file are copyright (c)2005-2006 by PROGIDISTRI - {@link http://progidistri.com/}.
19 *
20 * {@internal License choice
21 * - If you have received this file as part of a package, please find the license.txt file in
22 * the same folder or the closest folder above for complete license terms.
23 * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
24 * then you must choose one of the following licenses before using the file:
25 * - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
26 * - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
27 * }}
28 *
29 * {@internal Open Source relicensing agreement:
30 * Daniel HAHLER grants Francois PLANQUE the right to license
31 * Daniel HAHLER's contributions to this file and the b2evolution project
32 * under any OSI approved OSS license (http://www.opensource.org/licenses/).
33 *
34 * PROGIDISTRI S.A.S. grants Francois PLANQUE the right to license
35 * PROGIDISTRI S.A.S.'s contributions to this file and the b2evolution project
36 * under any OSI approved OSS license (http://www.opensource.org/licenses/).
37 * }}
38 *
39 * {@internal Below is a list of authors who have contributed to design/coding of this file: }}
40 * @author blueyed: Daniel HAHLER.
41 * @author fplanque: Francois PLANQUE.
42 *
43 * @package files19 * @package files
44 */20 */
45if( !defined('QP_MAIN_INIT') ) die( 'Please, do not access this page directly.' );21if(!defined('QP_MAIN_INIT')) die('fail');
4622
47/**23global $dispatcher;
48 * Filelist
49 * fp>> TODO: When the user is viewing details for a file he should (by default) not be presented with the filelist in addition to the file properties
50 * In cases like that, we should try to avoid instanciating a Filelist.
51 */
52load_class('files/model/_filelist.class.php');
53
54global $current_User;24global $current_User;
55global $dispatcher;
5625
57// Check global access permissions:26// Check global access permissions
58if( ! $Settings->get( 'fm_enabled' ) )27if( ! $Settings->get( 'fm_enabled' ) )
59{28{
60 // File Manager is disabled, so let's be kind and give them something to work with29 // File Manager is disabled, so give them something to work with
61 $AdminUI->set_coll_list_params( 'blog_ismember', 'view', array(), T_('Global'), '?blog=0' );30 $AdminUI->set_coll_list_params( 'blog_ismember', 'view', array(), T_('Global'), '?blog=0' );
62 $AdminUI->set_path( 'dashboard' );31 $AdminUI->set_path( 'dashboard' );
63 $AdminUI->disp_html_head();32 $AdminUI->disp_html_head();
@@ -67,58 +36,73 @@
67 die();36 die();
68}37}
6938
70// Check permission:39// Check permission
71$current_User->check_perm( 'files', 'view', true );40$current_User->check_perm( 'files', 'view', true );
7241
73$AdminUI->set_path( 'files', 'browse' );42$AdminUI->set_path( 'files', 'browse' );
7443
75// INIT params:44// INIT params
76if( param( 'root_and_path', 'string', '', false ) /* not memorized (default) */ && strpos( $root_and_path, '::' ) )45if( param( 'root_and_path', 'string', '', false ) /* not memorized (default) */ && strpos( $root_and_path, '::' ) )
77{ // root and path together: decode and override (used by "radio-click-dirtree")46{
47 // root and path together: decode and override (used by "radio-click-dirtree")
78 list( $root, $path ) = explode( '::', $root_and_path, 2 );48 list( $root, $path ) = explode( '::', $root_and_path, 2 );
79 // Memorize new root:49 // Memorize new root
80 memorize_param( 'root', 'string', NULL );50 memorize_param( 'root', 'string', NULL );
81 memorize_param( 'path', 'string', NULL );51 memorize_param( 'path', 'string', NULL );
82}52}
83else53else
84{54{
85 param( 'root', 'string', NULL, true ); // the root directory from the dropdown box (user_X or blog_X; X is ID - 'user' for current user (default))55 // the root directory from the dropdown box (user_X or blog_X; X is ID - 'user' for current user (default))
86 param( 'path', 'string', '/', true ); // the path relative to the root dir56 param( 'root', 'string', NULL, true );
87 if( param( 'new_root', 'string', '' )57
88 && $new_root != $root )58 // the path relative to the root dir
89 { // We have changed root in the select list59 param( 'path', 'string', '/', true );
60
61 if( param( 'new_root', 'string', '' ) && $new_root != $root )
62 {
63 // We have changed root in the select list
90 $root = $new_root;64 $root = $new_root;
91 $path = '';65 $path = '';
92 }66 }
93}67}
9468
95// Load linkable objects:69// Load linkable objects
96if( param( 'item_ID', 'integer', NULL, true, false, false ) )70if( param( 'item_ID', 'integer', NULL, true, false, false ) )
97{ // Load Requested iem:71{
72 // Load Requested iem
98 $ItemCache = & get_Cache( 'ItemCache' );73 $ItemCache = & get_Cache( 'ItemCache' );
99 if( ($edited_Item = & $ItemCache->get_by_ID( $item_ID, false )) === false )74
100 { // We could not find the contact to link:75 if( ( $edited_Item = & $ItemCache->get_by_ID( $item_ID, false ) ) === false )
76 {
77 // We could not find the contact to link
101 $Messages->add( T_('Requested item does not exist any longer.'), 'error' );78 $Messages->add( T_('Requested item does not exist any longer.'), 'error' );
102 unset( $edited_Item );79 unset( $edited_Item );
103 forget_param( 'item_ID' );80 forget_param( 'item_ID' );
104 unset( $item_ID );81 unset( $item_ID );
105 }82 }
83
106}84}
10785
108if( param( 'user_ID', 'integer', NULL, true, false, false ) )86if( param( 'user_ID', 'integer', NULL, true, false, false ) )
109{ // Load Requested user:87{
88 // Load Requested user
110 $UserCache = & get_Cache( 'UserCache' );89 $UserCache = & get_Cache( 'UserCache' );
111 if( ($edited_User = & $UserCache->get_by_ID( $user_ID, false )) === false )90
112 { // We could not find the contact to link:91 if( ( $edited_User = & $UserCache->get_by_ID( $user_ID, false ) ) === false )
92 {
93 // We could not find the contact to link
113 $Messages->add( T_('Requested user does not exist any longer.'), 'error' );94 $Messages->add( T_('Requested user does not exist any longer.'), 'error' );
114 unset( $edited_User );95 unset( $edited_User );
115 forget_param( 'user_ID' );96 forget_param( 'user_ID' );
116 unset( $user_ID );97 unset( $user_ID );
117 }98 }
118 else99 else
119 { // Found User, check perm:100 {
101 // Found User, check perm
120 if( $edited_User->ID != $current_User->ID )102 if( $edited_User->ID != $current_User->ID )
121 { // if not editing himself, must have user edit permission:103 {
104
105 // if not editing himself, must have user edit permission
122 if( ! $current_User->check_perm( 'users', 'edit' ) )106 if( ! $current_User->check_perm( 'users', 'edit' ) )
123 {107 {
124 $Messages->add( T_('No permission to edit this user.'), 'error' );108 $Messages->add( T_('No permission to edit this user.'), 'error' );
@@ -126,97 +110,101 @@
126 forget_param( 'user_ID' );110 forget_param( 'user_ID' );
127 unset( $user_ID );111 unset( $user_ID );
128 }112 }
113
129 }114 }
130115
131 }116 }
117
132}118}
133119
134/**
135 * @global string The file manager mode we're in ('fm_upload', 'fm_move')
136 */
137$fm_mode = param( 'fm_mode', 'string', NULL, true );120$fm_mode = param( 'fm_mode', 'string', NULL, true );
138121
139$action = param_action();122$action = param_action();
140if( $action == 'group_action' )123if( $action == 'group_action' )
141{ // Get the real action from the select:124{
125 // Get the real action from the select
142 $action = param( 'group_action', 'string', '' );126 $action = param( 'group_action', 'string', '' );
143}127}
144128
145if( !empty($action) && substr( $fm_mode, 0, 5 ) != 'link_' )129if( ! empty( $action ) && substr( $fm_mode, 0, 5 ) != 'link_' )
146{ // The only modes which can tolerate simultaneous actions at this time are link_* modes (item, user...)130{
131 // The only modes which can tolerate simultaneous actions at this time are link_* modes (item, user...)
147 // file_move & file_copy shouldn't actually be modes132 // file_move & file_copy shouldn't actually be modes
148 $fm_mode = '';133 $fm_mode = '';
149}134}
150135
151// Name of the iframe we want some actions to come back to:136// Name of the iframe we want some actions to come back to
152param( 'iframe_name', 'string', '', true );137param( 'iframe_name', 'string', '', true );
153138
154// Get root:139// Get root
155$ads_list_path = false; // false by default, gets set if we have a valid root140$ads_list_path = false; // false by default, gets set if we have a valid root
156/**
157 * @var FileRoot
158 */
159$fm_FileRoot = NULL;141$fm_FileRoot = NULL;
160
161$FileRootCache = & get_Cache( 'FileRootCache' );142$FileRootCache = & get_Cache( 'FileRootCache' );
162
163$available_Roots = $FileRootCache->get_available_FileRoots();143$available_Roots = $FileRootCache->get_available_FileRoots();
164144
165if( ! empty($root) )145if( ! empty( $root ) )
166{ // We have requested a root folder by string:146{
167 $fm_FileRoot = & $FileRootCache->get_by_ID($root, true);147 // We have requested a root folder by string
148 $fm_FileRoot = & $FileRootCache->get_by_ID( $root, true );
168149
169 if( ! $fm_FileRoot || ! isset( $available_Roots[$fm_FileRoot->ID] ) )150 if( ! $fm_FileRoot || ! isset( $available_Roots[$fm_FileRoot->ID] ) )
170 { // Root not found or not in list of available ones151 {
152 // Root not found or not in list of available ones
171 $Messages->add( T_('You don\'t have access to the requested root directory.'), 'error' );153 $Messages->add( T_('You don\'t have access to the requested root directory.'), 'error' );
172 $fm_FileRoot = false;154 $fm_FileRoot = false;
173 }155 }
174}156}
175elseif( !empty($edited_Item) )157elseif( ! empty( $edited_Item ) )
176{ // We have a post, check if it already has a linked file in a particular root, in which case we want to use that root!158{
177 // This is useful when whlicking "attach files" from teh post edit screen: it takes you to the root where you have159 // We have a post, check if it already has a linked file in a particular root, in
178 // already attached files from. Otherwise the next block below will default to the Blog's fileroot.160 // which case we want to use that root! This is useful when whlicking "attach files"
179 // Get list of attached files:161 // from the post edit screen: it takes you to the root where you have already attached
162 // files from. Otherwise the next block below will default to the Blog's fileroot.
163
164 // Get list of attached files
180 $FileList = $edited_Item->get_attachment_FileList( 1 );165 $FileList = $edited_Item->get_attachment_FileList( 1 );
181 // Get first file:166
182 /**167 // Get first file
183 * @var File
184 */
185 $File = & $FileList->get_next();168 $File = & $FileList->get_next();
186 if( !empty( $File ) )169 if( ! empty( $File ) )
187 { // Obtain and use file root of first file:170 {
171 // Obtain and use file root of first file
188 $fm_FileRoot = & $File->get_FileRoot();172 $fm_FileRoot = & $File->get_FileRoot();
189 $path = dirname( $File->get_rdfs_rel_path() ).'/';173 $path = dirname( $File->get_rdfs_rel_path() ).'/';
190 }174 }
175
191}176}
192177
193178if( empty( $fm_FileRoot ) && ! empty( $edited_User ) )
194if( empty($fm_FileRoot) && !empty($edited_User) )179{
195{ // Still not set a root, try to get it for the edited User180 // Still not set a root, try to get it for the edited User
196 $fm_FileRoot = & $FileRootCache->get_by_type_and_ID( 'user', $edited_User->ID );181 $fm_FileRoot = & $FileRootCache->get_by_type_and_ID( 'user', $edited_User->ID );
197 if( ! $fm_FileRoot || ! isset( $available_Roots[$fm_FileRoot->ID] ) )182 if( ! $fm_FileRoot || ! isset( $available_Roots[$fm_FileRoot->ID] ) )
198 { // Root not found or not in list of available ones183 {
184 // Root not found or not in list of available ones
199 $fm_FileRoot = false;185 $fm_FileRoot = false;
200 }186 }
201}187}
202188
203if( empty($fm_FileRoot) && !empty($Blog) )189if( empty( $fm_FileRoot ) && ! empty( $Blog ) )
204{ // Still not set a root, try to get it for the current Blog190{
191 // Still not set a root, try to get it for the current Blog
205 $fm_FileRoot = & $FileRootCache->get_by_type_and_ID( 'collection', $Blog->ID );192 $fm_FileRoot = & $FileRootCache->get_by_type_and_ID( 'collection', $Blog->ID );
206 if( ! $fm_FileRoot || ! isset( $available_Roots[$fm_FileRoot->ID] ) )193 if( ! $fm_FileRoot || ! isset( $available_Roots[$fm_FileRoot->ID] ) )
207 { // Root not found or not in list of available ones194 {
195 // Root not found or not in list of available ones
208 $fm_FileRoot = false;196 $fm_FileRoot = false;
209 }197 }
210}198}
211199
212
213if( ! $fm_FileRoot )200if( ! $fm_FileRoot )
214{ // No root requested (or the requested is invalid),201{
215 // get the first one available:202 // No root requested (or the requested is invalid), get the first one available
216 if( $available_Roots203 if( $available_Roots
217 && ( $tmp_keys = array_keys( $available_Roots ) )204 && ( $tmp_keys = array_keys( $available_Roots ) )
218 && $first_Root = & $available_Roots[ $tmp_keys[0] ] )205 && $first_Root = & $available_Roots[$tmp_keys[0]] )
219 { // get the first one206 {
207 // get the first one
220 $fm_FileRoot = & $first_Root;208 $fm_FileRoot = & $first_Root;
221 }209 }
222 else210 else
@@ -226,44 +214,50 @@
226}214}
227215
228if( $fm_FileRoot )216if( $fm_FileRoot )
229{ // We have access to a file root:217{
230 if( empty($fm_FileRoot->ads_path) )218 // We have access to a file root
231 { // Not sure it's possible to get this far, but just in case...219 if( empty( $fm_FileRoot->ads_path ) )
220 {
221 // Not sure it's possible to get this far, but just in case...
232 $Messages->add( sprintf( T_('The root directory &laquo;%s&raquo; does not exist.'), $fm_FileRoot->ads_path ), 'error' );222 $Messages->add( sprintf( T_('The root directory &laquo;%s&raquo; does not exist.'), $fm_FileRoot->ads_path ), 'error' );
233 }223 }
234 else224 else
235 { // Root exists225 {
236226 // Root exists
237 // Make sure $root is set:227 // Make sure $root is set
238 $root = $fm_FileRoot->ID;228 $root = $fm_FileRoot->ID;
239229
240 // Let's get into requested list dir...230 // Let's get into requested list dir...
241 $non_canonical_list_path = $fm_FileRoot->ads_path.$path;231 $non_canonical_list_path = $fm_FileRoot->ads_path.$path;
242232
243 // Dereference any /../ just to make sure, and CHECK if directory exists:233 // Dereference any /../ just to make sure, and CHECK if directory exists
244 $ads_list_path = get_canonical_path( $non_canonical_list_path );234 $ads_list_path = get_canonical_path( $non_canonical_list_path );
245235
246 if( !is_dir( $ads_list_path ) )236 if( ! is_dir( $ads_list_path ) )
247 { // This should never happen, but just in case the diretory does not exist:237 {
238 // This should never happen, but just in case the diretory does not exist
248 $Messages->add( sprintf( T_('The directory &laquo;%s&raquo; does not exist.'), $path ), 'error' );239 $Messages->add( sprintf( T_('The directory &laquo;%s&raquo; does not exist.'), $path ), 'error' );
249 $path = ''; // fp> added240 $path = ''; // fp> added
250 $ads_list_path = NULL;241 $ads_list_path = NULL;
251 }242 }
252 elseif( ! preg_match( '#^'.preg_quote($fm_FileRoot->ads_path, '#').'#', $ads_list_path ) )243 elseif( ! preg_match( '#^'.preg_quote( $fm_FileRoot->ads_path, '#' ).'#', $ads_list_path ) )
253 { // cwd is OUTSIDE OF root!244 {
245 // cwd is OUTSIDE OF root!
254 $Messages->add( T_( 'You are not allowed to go outside your root directory!' ), 'error' );246 $Messages->add( T_( 'You are not allowed to go outside your root directory!' ), 'error' );
255 $path = ''; // fp> added247 $path = ''; // fp> added
256 $ads_list_path = $fm_FileRoot->ads_path;248 $ads_list_path = $fm_FileRoot->ads_path;
257 }249 }
258 elseif( $ads_list_path != $non_canonical_list_path )250 elseif( $ads_list_path != $non_canonical_list_path )
259 { // We have reduced the absolute path, we should also reduce the relative $path (used in urls params)251 {
252 // We have reduced the absolute path, we should also reduce the relative $path (used in urls params)
260 $path = get_canonical_path( $path );253 $path = get_canonical_path( $path );
261 }254 }
262 }255 }
263}256}
264257
265if( empty($ads_list_path) )258if( empty( $ads_list_path ) )
266{ // We have no Root / list path, there was an error. Unset any action or mode.259{
260 // We have no Root / list path, there was an error. Unset any action or mode
267 $action = 'nil';261 $action = 'nil';
268 $fm_mode = NULL;262 $fm_mode = NULL;
269263
@@ -274,39 +268,25 @@
274 exit(0);268 exit(0);
275}269}
276270
277$Debuglog->add( 'root: '.var_export( $root, true ), 'files' );271// A list of filepaths which are selected in the FM list.
278$Debuglog->add( 'FM root: '.var_export( $fm_FileRoot, true ), 'files' );272// @todo fp> This could probably be further simpplified by using "fm_sources" for selections.
279$Debuglog->add( 'FM _ads_list_path: '.var_export( $ads_list_path, true ), 'files' );273// Note: fm_sources is better because it also handles sources/selections on a different fileroot
280$Debuglog->add( 'path: '.var_export( $path, true ), 'files' );
281
282
283/**
284 * A list of filepaths which are selected in the FM list.
285 *
286 * @todo fp> This could probably be further simpplified by using "fm_sources" for selections.
287 * Note: fm_sources is better because it also handles sources/selections on a different fileroot
288 *
289 * @global array
290 */
291$fm_selected = param( 'fm_selected', 'array', array(), true );274$fm_selected = param( 'fm_selected', 'array', array(), true );
292$Debuglog->add( count($fm_selected).' selected files/directories', 'files' );275
293/**276// The selected files (must be within current fileroot)
294 * The selected files (must be within current fileroot)
295 *
296 * @global Filelist
297 */
298$selected_Filelist = new Filelist( $fm_FileRoot, false );277$selected_Filelist = new Filelist( $fm_FileRoot, false );
299foreach( $fm_selected as $l_source_path )278foreach( $fm_selected as $l_source_path )
300{279{
301 $selected_Filelist->add_by_subpath( urldecode($l_source_path), true );280 $selected_Filelist->add_by_subpath( urldecode( $l_source_path ), true );
302}281}
303282
304// Load editable objects:283// Load editable objects
305if( param( 'link_ID', 'integer', NULL, false, false, false ) )284if( param( 'link_ID', 'integer', NULL, false, false, false ) )
306{285{
307 $LinkCache = & get_Cache( 'LinkCache' );286 $LinkCache = & get_Cache( 'LinkCache' );
308 if( ($edited_Link = & $LinkCache->get_by_ID( $link_ID, false )) === false )287 if( ( $edited_Link = & $LinkCache->get_by_ID( $link_ID, false ) ) === false )
309 { // We could not find the link to edit:288 {
289 // We could not find the link to edit
310 $Messages->add( T_('Requested link does not exist any longer.'), 'error' );290 $Messages->add( T_('Requested link does not exist any longer.'), 'error' );
311 unset( $edited_Link );291 unset( $edited_Link );
312 forget_param( 'link_ID' );292 forget_param( 'link_ID' );
@@ -317,188 +297,185 @@
317// Check actions that need early processing:297// Check actions that need early processing:
318if( $action == 'createnew' )298if( $action == 'createnew' )
319{299{
320 // Check permission:300 // Check permission
321 $current_User->check_perm( 'files', 'add', true );301 $current_User->check_perm( 'files', 'add', true );
322302
323 // create new file/dir303 // create new file/dir
324 param( 'create_type', 'string', true ); // 'file', 'dir'304 param( 'create_type', 'string', true ); // 'file', 'dir'
325305
326 $action = ( $create_type == 'file' ? 'createnew_file' : 'createnew_dir' );306 $action = ( $create_type == 'file' ? 'createnew_file' : 'createnew_dir' );
327}307}
328308
329switch( $action )309switch( $action )
330{310{
331 case 'filter':311 case 'filter':
332 $action = 'list';312 $action = 'list';
333 break;313 break;
334314
335 case 'filter_unset':315 case 'filter_unset':
336 // Clear filters!316 // Clear filters!
337 $fm_filter = '';317 $fm_filter = '';
338 $action = 'list';318 $action = 'list';
339 break;319 break;
340320
341 case 'createnew_dir':321 case 'createnew_dir':
342 // We are probably comming from 'createnew' but there is no guarantee!322 // We are probably comming from 'createnew' but there is no guarantee!
343 // Check permission:323
344 $current_User->check_perm( 'files', 'add', true );324 // Check permission
345325 $current_User->check_perm( 'files', 'add', true );
346 if( ! $Settings->get( 'fm_enable_create_dir' ) )326
347 { // Directory creation is gloablly disabled:327 if( ! $Settings->get( 'fm_enable_create_dir' ) )
348 $Messages->add( T_('Directory creation is disabled.'), 'error' );328 {
349 break;329 // Directory creation is gloablly disabled
350 }330 $Messages->add( T_('Directory creation is disabled.'), 'error' );
351331 break;
352 if( ! param( 'create_name', 'string', '' ) )332 }
353 { // No name was supplied:333
354 $Messages->add( T_('Cannot create a directory without name.'), 'error' );334 if( ! param( 'create_name', 'string', '' ) )
355 break;335 {
356 }336 // No name was supplied
357337 $Messages->add( T_('Cannot create a directory without name.'), 'error' );
358 if( $error_dirname = validate_dirname( $create_name ) )338 break;
359 { // Not valid dirname339 }
360 $Messages->add( $error_dirname, 'error' );340
361 break;341 if( $error_dirname = validate_dirname( $create_name ) )
362 }342 {
363343 // Not valid dirname
364 // Try to get File object:344 $Messages->add( $error_dirname, 'error' );
365 /**345 break;
366 * @var FileCache346 }
367 */347
368 $FileCache = & get_Cache( 'FileCache' );348 // Try to get File object
369 /**349 $FileCache = & get_Cache( 'FileCache' );
370 * @var File350 $newFile = & $FileCache->get_by_root_and_path( $fm_FileRoot->type, $fm_FileRoot->in_type_ID, $path.$create_name );
371 */351
372 $newFile = & $FileCache->get_by_root_and_path( $fm_FileRoot->type, $fm_FileRoot->in_type_ID, $path.$create_name );352 if( $newFile->exists() )
373353 {
374 if( $newFile->exists() )354 $Messages->add( sprintf( T_('The file &laquo;%s&raquo; already exists.'), $create_name ), 'error' );
375 {355 break;
376 $Messages->add( sprintf( T_('The file &laquo;%s&raquo; already exists.'), $create_name ), 'error' );356 }
377 break;357
378 }358 if( ! $newFile->create( $create_type ) )
379359 {
380 if( ! $newFile->create( $create_type ) )360 $Messages->add( sprintf( T_('Could not create directory &laquo;%s&raquo; in &laquo;%s&raquo;.'), $create_name, $fm_Filelist->_rds_list_path ), 'error' );
381 {361 }
382 $Messages->add( sprintf( T_('Could not create directory &laquo;%s&raquo; in &laquo;%s&raquo;.'), $create_name, $fm_Filelist->_rds_list_path ), 'error' );362
383 }363 $Messages->add( sprintf( T_('The directory &laquo;%s&raquo; has been created.'), $create_name ), 'success' );
384364
385 $Messages->add( sprintf( T_('The directory &laquo;%s&raquo; has been created.'), $create_name ), 'success' );365 header_redirect( regenerate_url( '', '', '', '&' ) );
386366 // $action = 'list';
387 header_redirect( regenerate_url( '', '', '', '&' ) );367 break;
388 // $action = 'list';
389 break;
390
391368
392 case 'createnew_file':369 case 'createnew_file':
393 // We are probably comming from 'createnew' but there is no guarantee!370 // We are probably comming from 'createnew' but there is no guarantee!
394 // Check permission:371 // Check permission
395 $current_User->check_perm( 'files', 'add', true );372 $current_User->check_perm( 'files', 'add', true );
396373
397 if( ! $Settings->get( 'fm_enable_create_file' ) )374 if( ! $Settings->get( 'fm_enable_create_file' ) )
398 { // File creation is gloablly disabled:375 {
399 $Messages->add( T_('File creation is disabled.'), 'error' );376 // File creation is gloablly disabled
400 break;377 $Messages->add( T_('File creation is disabled.'), 'error' );
401 }378 break;
402379 }
403 if( ! param( 'create_name', 'string', '' ) )380
404 { // No name was supplied:381 if( ! param( 'create_name', 'string', '' ) )
405 $Messages->add( T_('Cannot create a file without name.'), 'error' );382 {
406 break;383 // No name was supplied
407 }384 $Messages->add( T_('Cannot create a file without name.'), 'error' );
408 if( $error_filename = validate_filename( $create_name, $current_User->check_perm( 'files', 'all' ) ) )385 break;
409 { // Not valid filename or extension386 }
410 $Messages->add( $error_filename, 'error' );387
411 break;388 if( $error_filename = validate_filename( $create_name, $current_User->check_perm( 'files', 'all' ) ) )
412 }389 {
413390 // Not valid filename or extension
414 // Try to get File object:391 $Messages->add( $error_filename, 'error' );
415 $FileCache = & get_Cache( 'FileCache' );392 break;
416 $newFile = & $FileCache->get_by_root_and_path( $fm_FileRoot->type, $fm_FileRoot->in_type_ID, $path.$create_name );393 }
417394
418 if( $newFile->exists() )395 // Try to get File object
419 {396 $FileCache = & get_Cache( 'FileCache' );
420 $Messages->add( sprintf( T_('The file &laquo;%s&raquo; already exists.'), $create_name ), 'error' );397 $newFile = & $FileCache->get_by_root_and_path( $fm_FileRoot->type, $fm_FileRoot->in_type_ID, $path.$create_name );
421 break;398
422 }399 if( $newFile->exists() )
423400 {
424 if( ! $newFile->create( $create_type ) )401 $Messages->add( sprintf( T_('The file &laquo;%s&raquo; already exists.'), $create_name ), 'error' );
425 {402 break;
426 $Messages->add( sprintf( T_('Could not create file &laquo;%s&raquo; in &laquo;%s&raquo;.'), $create_name, $fm_Filelist->_rds_list_path ), 'error' );403 }
427 }404
428405 if( ! $newFile->create( $create_type ) )
429 $Messages->add( sprintf( T_('The file &laquo;%s&raquo; has been created.'), $create_name ), 'success' );406 {
430407 $Messages->add( sprintf( T_('Could not create file &laquo;%s&raquo; in &laquo;%s&raquo;.'), $create_name, $fm_Filelist->_rds_list_path ), 'error' );
431 header_redirect( regenerate_url( '', '', '', '&' ) );408 }
432 // $action = 'list';409
433 break;410 $Messages->add( sprintf( T_('The file &laquo;%s&raquo; has been created.'), $create_name ), 'success' );
434411
435412 header_redirect( regenerate_url( '', '', '', '&' ) );
436 case 'update_settings':413 // $action = 'list';
437 // Update settings NOW since they may affect the FileList414 break;
438 $UserSettings->set( 'fm_dirsnotattop', 1-param( 'option_dirsattop', 'integer', 0 ) );415
439 $UserSettings->set( 'fm_permlikelsl', param( 'option_permlikelsl', 'integer', 0 ) );416 case 'update_settings':
440 $UserSettings->set( 'fm_imglistpreview', param( 'option_imglistpreview', 'integer', 0 ) );417 // Update settings NOW since they may affect the FileList
441 $UserSettings->set( 'fm_getimagesizes', param( 'option_getimagesizes', 'integer', 0 ) );418 $UserSettings->set( 'fm_dirsnotattop', 1-param( 'option_dirsattop', 'integer', 0 ) );
442419 $UserSettings->set( 'fm_permlikelsl', param( 'option_permlikelsl', 'integer', 0 ) );
443 $UserSettings->set( 'fm_showtypes', param( 'option_showtypes', 'integer', 0 ) );420 $UserSettings->set( 'fm_imglistpreview', param( 'option_imglistpreview', 'integer', 0 ) );
444 $UserSettings->set( 'fm_showdate', param( 'option_showdate', 'string', 'compact' ) );421 $UserSettings->set( 'fm_getimagesizes', param( 'option_getimagesizes', 'integer', 0 ) );
445 $UserSettings->set( 'fm_showfsperms', param( 'option_showfsperms', 'integer', 0 ) );422 $UserSettings->set( 'fm_showtypes', param( 'option_showtypes', 'integer', 0 ) );
446 $UserSettings->set( 'fm_showfsowner', param( 'option_showfsowner', 'integer', 0 ) );423 $UserSettings->set( 'fm_showdate', param( 'option_showdate', 'string', 'compact' ) );
447 $UserSettings->set( 'fm_showfsgroup', param( 'option_showfsgroup', 'integer', 0 ) );424 $UserSettings->set( 'fm_showfsperms', param( 'option_showfsperms', 'integer', 0 ) );
448425 $UserSettings->set( 'fm_showfsowner', param( 'option_showfsowner', 'integer', 0 ) );
449 $UserSettings->set( 'fm_showhidden', param( 'option_showhidden', 'integer', 0 ) );426 $UserSettings->set( 'fm_showfsgroup', param( 'option_showfsgroup', 'integer', 0 ) );
450 $UserSettings->set( 'fm_recursivedirsize', param( 'option_recursivedirsize', 'integer', 0 ) );427 $UserSettings->set( 'fm_showhidden', param( 'option_showhidden', 'integer', 0 ) );
451 $UserSettings->set( 'fm_allowfiltering', param( 'option_allowfiltering', 'string', 'simple' ) );428 $UserSettings->set( 'fm_recursivedirsize', param( 'option_recursivedirsize', 'integer', 0 ) );
452429 $UserSettings->set( 'fm_allowfiltering', param( 'option_allowfiltering', 'string', 'simple' ) );
453 if( $UserSettings->dbupdate() )430
454 {431 if( $UserSettings->dbupdate() )
455 $Messages->add( T_('Your user settings have been updated.'), 'success' );432 {
456 }433 $Messages->add( T_('Your user settings have been updated.'), 'success' );
457434 }
458 header_redirect( regenerate_url( '', '', '', '&' ) );435
459 // $action = 'list';436 header_redirect( regenerate_url( '', '', '', '&' ) );
460 break;437 // $action = 'list';
438 break;
461439
462 case 'update_file':440 case 'update_file':
463 // Update File:441 // Update File
464442
465 if( $demo_mode )443 if( $demo_mode )
466 {444 {
467 $Messages->add( 'Sorry, you cannot update files in demo mode!', 'error' );445 $Messages->add( 'Sorry, you cannot update files in demo mode!', 'error' );
468 break;446 break;
469 }447 }
470448
471 // Check permission!449 // Check permission!
472 $current_User->check_perm( 'files', 'edit', true );450 $current_User->check_perm( 'files', 'edit', true );
473451
474 // Get the file we want to update:452 // Get the file we want to update
475 $edited_File = & $selected_Filelist->get_by_idx(0);453 $edited_File = & $selected_Filelist->get_by_idx(0);
476454
477 // Check that the file is editable:455 // Check that the file is editable
478 if( ! $edited_File->is_editable( $current_User->check_perm( 'files', 'all' ) ) )456 if( ! $edited_File->is_editable( $current_User->check_perm( 'files', 'all' ) ) )
479 {457 {
480 $Messages->add( sprintf( T_( 'You are not allowed to edit &laquo;%s&raquo;.' ), $edited_File->dget('name') ), 'error' );458 $Messages->add( sprintf( T_( 'You are not allowed to edit &laquo;%s&raquo;.' ), $edited_File->dget( 'name' ) ), 'error' );
481 break;459 break;
482 }460 }
483461
484 param( 'file_content', 'html', '', false );462 param( 'file_content', 'html', '', false );
485463
486464 $full_path = $edited_File->get_full_path();
487 $full_path = $edited_File->get_full_path();465 if( $rsc_handle = fopen( $full_path, 'w+') )
488 if( $rsc_handle = fopen( $full_path, 'w+') )466 {
489 {467 fwrite( $rsc_handle, $file_content );
490 fwrite( $rsc_handle, $file_content );468 fclose( $rsc_handle );
491 fclose( $rsc_handle );469 $Messages->add( sprintf( T_( 'The file &laquo;%s&raquo; has been updated.' ), $edited_File->dget( 'name' ) ), 'success' );
492 $Messages->add( sprintf( T_( 'The file &laquo;%s&raquo; has been updated.' ), $edited_File->dget('name') ), 'success' );470 }
493 }471 else
494 else472 {
495 {473 $Messages->add( sprintf( T_( 'The file &laquo;%s&raquo; could not be updated.' ), $edited_File->dget( 'name' ) ), 'error' );
496 $Messages->add( sprintf( T_( 'The file &laquo;%s&raquo; could not be updated.' ), $edited_File->dget('name') ), 'error' );474 }
497 }475
498476 header_redirect( regenerate_url( '', '', '', '&' ) );
499 header_redirect( regenerate_url( '', '', '', '&' ) );477 // $action = 'list';
500 // $action = 'list';478 break;
501 break;
502}479}
503480
504// Do we want to display the directory tree next to the files table481// Do we want to display the directory tree next to the files table
@@ -506,7 +483,6 @@
506483
507// Filelist484// Filelist
508$fm_Filelist = new Filelist( $fm_FileRoot, $ads_list_path );485$fm_Filelist = new Filelist( $fm_FileRoot, $ads_list_path );
509$Debuglog->add( 'FM _rds_list_path: '.var_export( $fm_Filelist->_rds_list_path, true ), 'files' );
510486
511param( 'fm_filter', '', NULL, true );487param( 'fm_filter', '', NULL, true );
512param( 'fm_filter_regex', 'integer', 0, true );488param( 'fm_filter_regex', 'integer', 0, true );
@@ -517,7 +493,7 @@
517 $fm_Filelist->_dirs_not_at_top = true;493 $fm_Filelist->_dirs_not_at_top = true;
518}494}
519495
520if( $UserSettings->param_Request( 'fm_recursivedirsize', 'fm_recursivedirsize', 'integer', 0 ) ) // TODO: check for permission? (Server load)496if( $UserSettings->param_Request( 'fm_recursivedirsize', 'fm_recursivedirsize', 'integer', 0 ) ) // @todo (0000): check for permission? (Server load)
521{497{
522 $fm_Filelist->_use_recursive_dirsize = true;498 $fm_Filelist->_use_recursive_dirsize = true;
523}499}
@@ -548,938 +524,936 @@
548switch( $action )524switch( $action )
549{525{
550 case 'download':526 case 'download':
551 // TODO: We don't need the Filelist, move UP!527 // @todo (0000): provide optional zip formats (tgz, ..) - the used lib provides more
552 // TODO: provide optional zip formats (tgz, ..) - the used lib provides more..528 // @todo (0000): use "inmemory"=>false, so that you can download bigger archives faster!
553 // TODO: use "inmemory"=>false, so that you can download bigger archives faster!529
554530 $action_title = T_('Download');
555 $action_title = T_('Download');531
556532 if( !$selected_Filelist->count() )
557 if( !$selected_Filelist->count() )533 {
558 {534 $Messages->add( T_('Nothing selected.'), 'error' );
559 $Messages->add( T_('Nothing selected.'), 'error' );535 $action = 'list';
560 $action = 'list';536 break;
561 break;537 }
562 }538
563539 param( 'zipname', 'string', '' );
564 param( 'zipname', 'string', '' );540 param( 'exclude_sd', 'integer', 0 );
565 param( 'exclude_sd', 'integer', 0 );541
566542 if( empty( $zipname ) )
567 if( empty($zipname) )543 {
568 {544 if( param( 'action_invoked', 'integer', 0 ) )
569 if( param( 'action_invoked', 'integer', 0 ) )545 {
570 { // Action was invoked, add "hint"546 // Action was invoked, add "hint"
571 param_error( 'zipname', T_('Please provide the name of the archive.') );547 param_error( 'zipname', T_('Please provide the name of the archive.') );
572 }548 }
573 if( $selected_Filelist->count() == 1 )549 if( $selected_Filelist->count() == 1 )
574 {550 {
575 $only_File = $selected_Filelist->get_array();551 $only_File = $selected_Filelist->get_array();
576 $only_File = $only_File[0];552 $only_File = $only_File[0];
577553
578 // TODO: once we support additional formats, use the default extension here:554 // @todo (0000): once we support additional formats, use the default extension here
579 $zipname = $only_File->get_name().'.zip';555 $zipname = $only_File->get_name().'.zip';
580 }556 }
581 break;557 break;
582 }558 }
583559
584 // Downloading560 // Downloading
585 load_class('_ext/_zip_archives.php');561 $arraylist = $selected_Filelist->get_array( 'get_rdfs_rel_path' );
586562
587 $arraylist = $selected_Filelist->get_array( 'get_rdfs_rel_path' );563 $options = array(
588564 'basedir' => $fm_Filelist->get_ads_list_path(),
589 $options = array (565 'inmemory' => 1,
590 'basedir' => $fm_Filelist->get_ads_list_path(),566 'recurse' => (1 - $exclude_sd),
591 'inmemory' => 1,567 );
592 'recurse' => (1 - $exclude_sd),568
593 );569 $zipfile = new zip_file( $zipname );
594570 $zipfile->set_options( $options );
595 $zipfile = new zip_file( $zipname );571 $zipfile->add_files( $arraylist );
596 $zipfile->set_options( $options );572 $zipfile->create_archive();
597 $zipfile->add_files( $arraylist );573
598 $zipfile->create_archive();574 if( $zipfile->error )
599575 {
600 if( $zipfile->error )576 foreach( $zipfile->error as $v )
601 {577 {
602 foreach($zipfile->error as $v)578 $Messages->add( $v, 'error' );
603 {579 }
604 $Messages->add( $v, 'error' );580 break;
605 }581 }
606 break;582
607 }583 $zipfile->download_file();
608584 exit(0);
609 $zipfile->download_file();585 /* EXITED! */
610 exit(0);
611 /* EXITED! */
612586
613587
614 case 'rename':588 case 'rename':
615 // TODO: We don't need the Filelist, move UP!589 // Rename a file
616 // Rename a file:590
617591 // This will not allow to overwrite existing files, the same way Windows and MacOS
618 // This will not allow to overwrite existing files, the same way Windows and MacOS do not allow it. Adding an option will only clutter the interface and satisfy geeks only.592 // do not allow it. Adding an option will only clutter the interface and satisfy geeks only.
619 if( ! $current_User->check_perm( 'files', 'edit' ) )593 if( ! $current_User->check_perm( 'files', 'edit' ) )
620 { // We do not have permission to edit files594 {
621 $Messages->add( T_('You have no permission to edit/modify files.'), 'error' );595 // We do not have permission to edit files
622 $action = 'list';596 $Messages->add( T_('You have no permission to edit/modify files.'), 'error' );
623 break;597 $action = 'list';
624 }598 break;
625599 }
626 $allow_locked_filetypes = $current_User->check_perm( 'files', 'all' );600
627601 $allow_locked_filetypes = $current_User->check_perm( 'files', 'all' );
628 if( ! $selected_Filelist->count() )602
629 { // There is nothing to rename603 if( ! $selected_Filelist->count() )
630 $Messages->add( T_('Nothing selected.'), 'error' );604 {
631 $action = 'list';605 // There is nothing to rename
632 break;606 $Messages->add( T_('Nothing selected.'), 'error' );
633 }607 $action = 'list';
634608 break;
635 param( 'confirmed', 'integer', 0 );609 }
636 param( 'new_names', 'array', array() );610
637611 param( 'confirmed', 'integer', 0 );
638 // Check params for each file to rename:612 param( 'new_names', 'array', array() );
613
614 // Check params for each file to rename
615 while( $loop_src_File = & $selected_Filelist->get_next() )
616 {
617 if( ! isset( $new_names[$loop_src_File->get_md5_ID()] ) )
618 {
619 // We have not yet provided a name to rename to...
620 $confirmed = 0;
621 $new_names[$loop_src_File->get_md5_ID()] = $loop_src_File->get_name();
622 continue;
623 }
624
625 // Check if provided name is okay
626 $new_names[$loop_src_File->get_md5_ID()] = trim( strip_tags( $new_names[$loop_src_File->get_md5_ID()] ) );
627
628 if( !$loop_src_File->is_dir() )
629 {
630 if( $error_filename = validate_filename( $new_names[$loop_src_File->get_md5_ID()], $allow_locked_filetypes ) )
631 {
632 // Not a file name or not an allowed extension
633 $confirmed = 0;
634 param_error( 'new_names['.$loop_src_File->get_md5_ID().']', $error_filename );
635 continue;
636 }
637 }
638 elseif( $error_dirname = validate_dirname( $new_names[$loop_src_File->get_md5_ID()] ) )
639 {
640 // directory name
641 $confirmed = 0;
642 param_error( 'new_names['.$loop_src_File->get_md5_ID().']', $error_dirname );
643 continue;
644 }
645 }
646
647 if( $confirmed )
648 {
649 // Rename is confirmed, let's proceed
650 $selected_Filelist->restart();
639 while( $loop_src_File = & $selected_Filelist->get_next() )651 while( $loop_src_File = & $selected_Filelist->get_next() )
640 {652 {
641 if( ! isset( $new_names[$loop_src_File->get_md5_ID()] ) )653 $old_name = $loop_src_File->get_name();
642 { // We have not yet provided a name to rename to...654 $new_name = $new_names[$loop_src_File->get_md5_ID()];
643 $confirmed = 0;655
644 $new_names[$loop_src_File->get_md5_ID()] = $loop_src_File->get_name();656 if( $new_name == $old_name )
645 continue;657 {
646 }658 // Name has not changed...
647659 $Messages->add( sprintf( T_('&laquo;%s&raquo; has not been renamed'), $old_name ), 'note' );
648 // Check if provided name is okay:660 continue;
649 $new_names[$loop_src_File->get_md5_ID()] = trim(strip_tags($new_names[$loop_src_File->get_md5_ID()]));661 }
650662 // Perform rename
651 if( !$loop_src_File->is_dir() )663 if( ! $loop_src_File->rename_to( $new_name ) )
652 {664 {
653 if( $error_filename = validate_filename( $new_names[$loop_src_File->get_md5_ID()], $allow_locked_filetypes ) )665 $Messages->add( sprintf( T_('&laquo;%s&raquo; could not be renamed to &laquo;%s&raquo;'),
654 { // Not a file name or not an allowed extension666 $old_name, $new_name ), 'error' );
655 $confirmed = 0;667 continue;
656 param_error( 'new_names['.$loop_src_File->get_md5_ID().']', $error_filename );668 }
657 continue;669
658 }670 // We have moved in same dir, update caches
659 }671 $fm_Filelist->update_caches();
660 elseif( $error_dirname = validate_dirname( $new_names[$loop_src_File->get_md5_ID()] ) )672
661 { // directory name673 if( $fm_Filelist->contains( $loop_src_File ) === false )
662 $confirmed = 0;674 {
663 param_error( 'new_names['.$loop_src_File->get_md5_ID().']', $error_dirname );675 // File not in filelist (expected if not same dir)
664 continue;676 $fm_Filelist->add( $File );
665 }677 }
666 }678
667679 $Messages->add( sprintf( T_('&laquo;%s&raquo; has been successfully renamed to &laquo;%s&raquo;'),
668 if( $confirmed )680 $old_name, $new_name ), 'success' );
669 { // Rename is confirmed, let's proceed:681 }
670 $selected_Filelist->restart();682
671 while( $loop_src_File = & $selected_Filelist->get_next() )683 // REDIRECT / EXIT
672 {684 header_redirect( regenerate_url( '', '', '', '&' ) );
673 $old_name = $loop_src_File->get_name();685 // $action = 'list';
674 $new_name = $new_names[$loop_src_File->get_md5_ID()];686 }
675687 break;
676 if( $new_name == $old_name )
677 { // Name has not changed...
678 $Messages->add( sprintf( T_('&laquo;%s&raquo; has not been renamed'), $old_name ), 'note' );
679 continue;
680 }
681 // Perform rename:
682 if( ! $loop_src_File->rename_to( $new_name ) )
683 {
684 $Messages->add( sprintf( T_('&laquo;%s&raquo; could not be renamed to &laquo;%s&raquo;'),
685 $old_name, $new_name ), 'error' );
686 continue;
687 }
688
689 // We have moved in same dir, update caches:
690 $fm_Filelist->update_caches();
691
692 if( $fm_Filelist->contains( $loop_src_File ) === false )
693 { // File not in filelist (expected if not same dir)
694 $fm_Filelist->add( $File );
695 }
696
697
698 $Messages->add( sprintf( T_('&laquo;%s&raquo; has been successfully renamed to &laquo;%s&raquo;'),
699 $old_name, $new_name ), 'success' );
700 }
701
702 // REDIRECT / EXIT
703 header_redirect( regenerate_url( '', '', '', '&' ) );
704 // $action = 'list';
705 }
706 break;
707
708688
709 case 'delete':689 case 'delete':
710 // TODO: We don't need the Filelist, move UP!690 // Delete a file or directory
711 // Delete a file or directory:691
712692 if( ! $current_User->check_perm( 'files', 'edit' ) )
713 if( ! $current_User->check_perm( 'files', 'edit' ) )693 {
714 { // We do not have permission to edit files694 // We do not have permission to edit files
715 $Messages->add( T_('You have no permission to edit/modify files.'), 'error' );695 $Messages->add( T_('You have no permission to edit/modify files.'), 'error' );
716 $action = 'list';696 $action = 'list';
717 break;697 break;
698 }
699
700 if( ! $selected_Filelist->count() )
701 {
702 $Messages->add( T_('Nothing selected.'), 'error' );
703 $action = 'list';
704 break;
705 }
706
707 param( 'confirmed', 'integer', 0 );
708 // fplanque>> We cannot actually offer to delete subdirs since we cannot pre-check DB
709
710 $selected_Filelist->restart();
711 if( $confirmed )
712 {
713 // Unlink files
714 while( $l_File = & $selected_Filelist->get_next() )
715 {
716 if( $l_File->unlink() )
717 {
718 $Messages->add( sprintf( ( $l_File->is_dir() ? T_('The directory &laquo;%s&raquo; has been deleted.')
719 : T_('The file &laquo;%s&raquo; has been deleted.') ), $l_File->dget( 'name' ) ), 'success' );
720 $fm_Filelist->remove( $l_File );
721 }
722 else
723 {
724 $Messages->add( sprintf( ( $l_File->is_dir() ? T_('Could not delete the directory &laquo;%s&raquo; (not empty?).')
725 : T_('Could not delete the file &laquo;%s&raquo;.') ), $l_File->dget( 'name' ) ), 'error' );
726 }
727 }
728 $action = 'list';
729 }
730 else
731 {
732 // make sure we have loaded metas for all files in selection!
733 $selected_Filelist->load_meta();
734
735 // Check if there are delete restrictions on the files
736 while( $l_File = & $selected_Filelist->get_next() )
737 {
738 // Check if there are delete restrictions on this file.
739 // We use a callback here to display the post titles.
740 $l_File->check_relations( 'delete_restrictions', array(),
741 array( 'link_file_ID' => array( 'cb' => array( $l_File, 'cb_delete_restrictions_detail' ), ),
742 ) );
743
744 if( $Messages->count('restrict') )
745 {
746 // There are restrictions
747 $Messages->add( sprintf( T_('%s cannot be deleted because of the following relations:'),
748 $l_File->get_prefixed_name() ).
749 $Messages->display( NULL, NULL, false, 'restrict', '', 'ul', false ) );
750 $Messages->clear( 'restrict' );
751
752 // remove it from the list of selected files (that will be offered to delete)
753 $selected_Filelist->remove( $l_File );
754 }
718 }755 }
719756
720 if( ! $selected_Filelist->count() )757 if( ! $selected_Filelist->count() )
721 {758 {
722 $Messages->add( T_('Nothing selected.'), 'error' );759 // no files left in list, cancel action
723 $action = 'list';760 $action = 'list';
724 break;761 }
725 }762 }
726763 break;
727 param( 'confirmed', 'integer', 0 );
728 // fplanque>> We cannot actually offer to delete subdirs since we cannot pre-check DB
729
730 $selected_Filelist->restart();
731 if( $confirmed )
732 { // Unlink files:
733 while( $l_File = & $selected_Filelist->get_next() )
734 {
735 if( $l_File->unlink() )
736 {
737 $Messages->add( sprintf( ( $l_File->is_dir() ? T_('The directory &laquo;%s&raquo; has been deleted.')
738 : T_('The file &laquo;%s&raquo; has been deleted.') ), $l_File->dget('name') ), 'success' );
739 $fm_Filelist->remove( $l_File );
740 }
741 else
742 {
743 $Messages->add( sprintf( ( $l_File->is_dir() ? T_('Could not delete the directory &laquo;%s&raquo; (not empty?).')
744 : T_('Could not delete the file &laquo;%s&raquo;.') ), $l_File->dget('name') ), 'error' );
745 }
746 }
747 $action = 'list';
748 }
749 else
750 {
751 // make sure we have loaded metas for all files in selection!
752 $selected_Filelist->load_meta();
753
754 // Check if there are delete restrictions on the files:
755 while( $l_File = & $selected_Filelist->get_next() )
756 {
757 // Check if there are delete restrictions on this file.
758 // We use a callback here to display the post titles.
759 $l_File->check_relations( 'delete_restrictions', array(), array(
760 'link_file_ID' => array(
761 'cb' => array( $l_File, 'cb_delete_restrictions_detail' ),
762 ),
763 ) );
764
765 if( $Messages->count('restrict') )
766 { // There are restrictions:
767 $Messages->add( sprintf( T_('%s cannot be deleted because of the following relations:'),
768 $l_File->get_prefixed_name() ).
769 $Messages->display( NULL, NULL, false, 'restrict', '', 'ul', false ) );
770 $Messages->clear( 'restrict' );
771
772 // remove it from the list of selected files (that will be offered to delete):
773 $selected_Filelist->remove( $l_File );
774 }
775 }
776
777 if( ! $selected_Filelist->count() )
778 { // no files left in list, cancel action
779 $action = 'list';
780 }
781 }
782 break;
783
784764
785 case 'make_post':765 case 'make_post':
786 case 'make_posts':766 case 'make_posts':
787 // TODO: We don't need the Filelist, move UP!767 // Make posts with selected images
788 // Make posts with selected images:768 if( ! $selected_Filelist->count() )
789769 {
790 if( ! $selected_Filelist->count() )770 $Messages->add( T_('Nothing selected.'), 'error' );
791 {771 $action = 'list';
792 $Messages->add( T_('Nothing selected.'), 'error' );772 break;
793 $action = 'list';773 }
794 break;774
795 }775 // fp> TODO: this block should move to a general level
796776 // Try to go to the right blog:
797 // fp> TODO: this block should move to a general level777 if( $fm_Filelist->get_root_type() == 'collection' )
798 // Try to go to the right blog:778 {
799 if( $fm_Filelist->get_root_type() == 'collection' )779 set_working_blog( $fm_Filelist->get_root_ID() );
800 {780 // Load the blog we're in
801 set_working_blog( $fm_Filelist->get_root_ID() );781 $Blog = & $BlogCache->get_by_ID( $blog );
802 // Load the blog we're in:782 }
803 $Blog = & $BlogCache->get_by_ID( $blog );783
804 }784 // ---
805 // ---785 if( empty( $Blog ) )
806786 {
807787 $Messages->add( T_('No destination blog is selected.'), 'error' );
808 if( empty( $Blog ) )788 break;
809 {789 }
810 $Messages->add( T_('No destination blog is selected.'), 'error' );790 // $Blog->disp('name');
811 break;791
812 }792 // Get default status (includes PERM CHECK)
813 //$Blog->disp('name');793 $item_status = $Blog->get_allowed_item_status();
814794 if( empty( $item_status ) )
815 // Get default status (includes PERM CHECK):795 {
816 $item_status = $Blog->get_allowed_item_status();796 $Messages->add( T_('Sorry, you have no permission to post into this blog.'), 'error' );
817 if( empty($item_status) )797 break;
818 {798 }
819 $Messages->add( T_('Sorry, you have no permission to post into this blog.'), 'error' );799
820 break;800 // make sure we have loaded metas for all files in selection!
821 }801 $selected_Filelist->load_meta();
822802
823 // make sure we have loaded metas for all files in selection!803 // Ready to create post(s)
824 $selected_Filelist->load_meta();804 switch( $action )
825805 {
826 // Ready to create post(s):806 // SINGLE POST
827 load_class('items/model/_item.class.php');807 case 'make_post':
828808 // Create a post
829 switch( $action )809 $edited_Item = new Item();
830 {810 $edited_Item->set( 'status', $item_status );
831 case 'make_post':811 $edited_Item->set( 'main_cat_ID', $Blog->get_default_cat_ID() );
832 // SINGLE POST:812
833 // Create a post:813 $l_File = & $selected_Filelist->get_next();
834 $edited_Item = new Item();814
835 $edited_Item->set( 'status', $item_status );815 $title = $l_File->get( 'title' );
836 $edited_Item->set( 'main_cat_ID', $Blog->get_default_cat_ID() );816 if( empty( $title ) )
837817 {
838 $l_File = & $selected_Filelist->get_next();818 $title = $l_File->get( 'name' );
839819 }
840 $title = $l_File->get('title');820 $edited_Item->set( 'title', $title );
841 if( empty($title) )821
842 {822 $DB->begin();
843 $title = $l_File->get('name');823
844 }824 // INSERT NEW POST INTO DB
845 $edited_Item->set( 'title', $title );825 $edited_Item->dbinsert();
846826
847 $DB->begin();827 do
848828 {
849 // INSERT NEW POST INTO DB:829 // LOOP Through images
850 $edited_Item->dbinsert();830 if( ! $l_File->is_image() )
851831 {
852 do832 $Messages->add( sprintf( T_('Cannot post &laquo;%s&raquo; because it is not an image.'), $l_File->dget( 'name' ) ), 'error' );
853 { // LOOP Through images:833 continue;
854 if( ! $l_File->is_image() )834 }
855 {835
856 $Messages->add( sprintf( T_('Cannot post &laquo;%s&raquo; because it is not an image.'), $l_File->dget('name') ), 'error' );836 if( $l_File->meta == 'notfound' )
857 continue;837 {
858 }838 // That file has no meta data yet, create it now!
859839 $l_File->dbsave();
860 if( $l_File->meta == 'notfound' )840 }
861 { // That file has no meta data yet, create it now!841
862 $l_File->dbsave();842 // Let's make the link!
863 }843 $edited_Link = new Link();
864844 $edited_Link->set( 'itm_ID', $edited_Item->ID );
865 // Let's make the link!845 $edited_Link->set( 'file_ID', $l_File->ID );
866 $edited_Link = new Link();846 $edited_Link->dbinsert();
867 $edited_Link->set( 'itm_ID', $edited_Item->ID );847
868 $edited_Link->set( 'file_ID', $l_File->ID );848 $Messages->add( sprintf( T_('&laquo;%s&raquo; has been attached.'), $l_File->dget( 'name' ) ), 'success' );
869 $edited_Link->dbinsert();849
870850 } while( $l_File = & $selected_Filelist->get_next() );
871 $Messages->add( sprintf( T_('&laquo;%s&raquo; has been attached.'), $l_File->dget('name') ), 'success' );851
872852 $DB->commit();
873 } while( $l_File = & $selected_Filelist->get_next() );853
874854 header_redirect( $dispatcher.'?ctrl=items&action=edit&p='.$edited_Item->ID ); // Will save $Messages
875 $DB->commit();855 break;
876856
877 header_redirect( $dispatcher.'?ctrl=items&action=edit&p='.$edited_Item->ID ); // Will save $Messages857 case 'make_posts':
878 break;858 // MULTIPLE POST (1 per image)
879859 while( $l_File = & $selected_Filelist->get_next() )
880 case 'make_posts':860 {
881 // MULTIPLE POST (1 per image):861 if( ! $l_File->is_image() )
882 while( $l_File = & $selected_Filelist->get_next() )862 {
883 {863 $Messages->add( sprintf( T_('Cannot post &laquo;%s&raquo; because it is not an image.'), $l_File->dget( 'name' ) ), 'error' );
884 if( ! $l_File->is_image() )864 continue;
885 {865 }
886 $Messages->add( sprintf( T_('Cannot post &laquo;%s&raquo; because it is not an image.'), $l_File->dget('name') ), 'error' );866
887 continue;867 // Create a post
888 }868 $edited_Item = new Item();
889869 $edited_Item->set( 'status', $item_status );
890 // Create a post:870 $edited_Item->set( 'main_cat_ID', $Blog->get_default_cat_ID() );
891 $edited_Item = new Item();871
892 $edited_Item->set( 'status', $item_status );872 $title = $l_File->get( 'title' );
893 $edited_Item->set( 'main_cat_ID', $Blog->get_default_cat_ID() );873 if( empty( $title ) )
894874 {
895 $title = $l_File->get('title');875 $title = $l_File->get( 'name' );
896 if( empty($title) )876 }
897 {877 $edited_Item->set( 'title', $title );
898 $title = $l_File->get('name');878
899 }879 $DB->begin();
900 $edited_Item->set( 'title', $title );880
901881 // INSERT NEW POST INTO DB
902 $DB->begin();882 $edited_Item->dbinsert();
903883
904 // INSERT NEW POST INTO DB:884 if( $l_File->meta == 'notfound' )
905 $edited_Item->dbinsert();885 {
906886 // That file has no meta data yet, create it now!
907 if( $l_File->meta == 'notfound' )887 $l_File->dbsave();
908 { // That file has no meta data yet, create it now!888 }
909 $l_File->dbsave();889
910 }890 // Let's make the link!
911891 $edited_Link = new Link();
912 // Let's make the link!892 $edited_Link->set( 'itm_ID', $edited_Item->ID );
913 $edited_Link = new Link();893 $edited_Link->set( 'file_ID', $l_File->ID );
914 $edited_Link->set( 'itm_ID', $edited_Item->ID );894 $edited_Link->dbinsert();
915 $edited_Link->set( 'file_ID', $l_File->ID );895
916 $edited_Link->dbinsert();896 $DB->commit();
917897
918 $DB->commit();898 $Messages->add( sprintf( T_('&laquo;%s&raquo; has been posted.'), $l_File->dget( 'name' ) ), 'success' );
919899 }
920 $Messages->add( sprintf( T_('&laquo;%s&raquo; has been posted.'), $l_File->dget('name') ), 'success' );900
921 }901 // Note: we redirect without restoring filter. This should allow to see the new files.
922902 // &filter=restore
923 // Note: we redirect without restoring filter. This should allow to see the new files.903 header_redirect( $dispatcher.'?ctrl=items&blog='.$blog ); // Will save $Messages
924 // &filter=restore904
925 header_redirect( $dispatcher.'?ctrl=items&blog='.$blog ); // Will save $Messages905 break;
926906 }
927 break;907
928 }908 // Note: we should have EXITED here. In case we don't (error, or sth...)
929909 // Reset stuff so it doesn't interfere with upcomming display
930 // Note: we should have EXITED here. In case we don't (error, or sth...)910 unset( $edited_Item );
931911 unset( $edited_Link );
932 // Reset stuff so it doesn't interfere with upcomming display912 $selected_Filelist = new Filelist( $fm_Filelist->get_FileRoot(), false );
933 unset( $edited_Item );913 break;
934 unset( $edited_Link );914
935 $selected_Filelist = new Filelist( $fm_Filelist->get_FileRoot(), false );915 // Edit Text File
936 break;
937
938
939 case 'edit_file':916 case 'edit_file':
940 // TODO: We don't need the Filelist, move UP!917
941 // Edit Text File918 // Check permission!
942919 $current_User->check_perm( 'files', 'edit', true );
943 // Check permission!920
944 $current_User->check_perm( 'files', 'edit', true );921 // Get the file we want to edit
945922 $edited_File = & $selected_Filelist->get_by_idx(0);
946 // Get the file we want to edit:923
947 $edited_File = & $selected_Filelist->get_by_idx(0);924 // Check that the file is editable
948925 if( ! $edited_File->is_editable( $current_User->check_perm( 'files', 'all' ) ) )
949 // Check that the file is editable:926 {
950 if( ! $edited_File->is_editable( $current_User->check_perm( 'files', 'all' ) ) )927 $Messages->add( sprintf( T_( 'You are not allowed to edit &laquo;%s&raquo;.' ), $edited_File->dget( 'name' ) ), 'error' );
951 {928 // Leave special display mode
952 $Messages->add( sprintf( T_( 'You are not allowed to edit &laquo;%s&raquo;.' ), $edited_File->dget('name') ), 'error' );929 $action = 'list';
953 // Leave special display mode:
954 $action = 'list';
955 break;
956 }
957
958 $full_path = $edited_File->get_full_path();
959 if( $size = filesize($full_path) )
960 {
961 $rsc_handle = fopen( $full_path, 'r');
962 $edited_File->content = fread( $rsc_handle, $size );
963 fclose( $rsc_handle );
964 }
965 else
966 { // Empty file
967 $edited_File->content = '';
968 }
969 break;930 break;
970931 }
971932
933 $full_path = $edited_File->get_full_path();
934 if( $size = filesize( $full_path ) )
935 {
936 $rsc_handle = fopen( $full_path, 'r');
937 $edited_File->content = fread( $rsc_handle, $size );
938 fclose( $rsc_handle );
939 }
940 else
941 {
942 // Empty file
943 $edited_File->content = '';
944 }
945 break;
946
947 // Edit File properties (Meta Data)
972 case 'edit_properties':948 case 'edit_properties':
973 // TODO: We don't need the Filelist, move UP!949 // Check permission!
974 // Edit File properties (Meta Data)950 $current_User->check_perm( 'files', 'edit', true );
975951
976 // Check permission!952 $edited_File = & $selected_Filelist->get_by_idx(0);
977 $current_User->check_perm( 'files', 'edit', true );953 $edited_File->load_meta();
978954 break;
979 $edited_File = & $selected_Filelist->get_by_idx(0);955
980 $edited_File->load_meta();956 // Update File properties (Meta Data); on success this ends the file_properties mode
981 break;
982
983
984 case 'update_properties':957 case 'update_properties':
985 // TODO: We don't need the Filelist, move UP!958 // Check permission!
986 // Update File properties (Meta Data); on success this ends the file_properties mode:959 $current_User->check_perm( 'files', 'edit', true );
987960
988 // Check permission!961 $edited_File = & $selected_Filelist->get_by_idx(0);
989 $current_User->check_perm( 'files', 'edit', true );962 // Load meta data
990963 $edited_File->load_meta();
991 $edited_File = & $selected_Filelist->get_by_idx(0);964
992 // Load meta data:965 $edited_File->set( 'title', param( 'title', 'string', '' ) );
993 $edited_File->load_meta();966 $edited_File->set( 'alt', param( 'alt', 'string', '' ) );
994967 $edited_File->set( 'desc', param( 'desc', 'string', '' ) );
995 $edited_File->set( 'title', param( 'title', 'string', '' ) );968
996 $edited_File->set( 'alt', param( 'alt', 'string', '' ) );969 // Store File object into DB
997 $edited_File->set( 'desc', param( 'desc', 'string', '' ) );970 if( $edited_File->dbsave() )
998971 {
999 // Store File object into DB:972 $Messages->add( sprintf( T_( 'File properties for &laquo;%s&raquo; have been updated.' ), $edited_File->dget( 'name' ) ), 'success' );
1000 if( $edited_File->dbsave() )973 }
1001 {974 else
1002 $Messages->add( sprintf( T_( 'File properties for &laquo;%s&raquo; have been updated.' ), $edited_File->dget('name') ), 'success' );975 {
1003 }976 $Messages->add( sprintf( T_( 'File properties for &laquo;%s&raquo; have not changed.' ), $edited_File->dget( 'name' ) ), 'note' );
1004 else977 }
1005 {978 break;
1006 $Messages->add( sprintf( T_( 'File properties for &laquo;%s&raquo; have not changed.' ), $edited_File->dget('name') ), 'note' );
1007 }
1008 break;
1009979
1010980
1011 case 'link_user':981 case 'link_user':
1012 // TODO: We don't need the Filelist, move UP!982 // Link File (Avatar) to User
1013 // Link File to User:983 if( ! isset( $edited_User ) )
1014 if( ! isset($edited_User) )984 {
1015 { // No User to link to985 // No User to link to
1016 $fm_mode = NULL; // not really needed but just n case...986 $fm_mode = NULL; // not really needed but just in case...
1017 break;987 break;
1018 }988 }
1019989
1020 // Permission HAS been checked on top of controller!990 // Permission HAS been checked on top of controller!
1021991
1022 // Get the file we want to link:992 // Get the file we want to link
1023 if( !$selected_Filelist->count() )993 if( ! $selected_Filelist->count() )
1024 {994 {
1025 $Messages->add( T_('Nothing selected.'), 'error' );995 $Messages->add( T_('Nothing selected.'), 'error' );
1026 break;996 break;
1027 }997 }
1028 $edited_File = & $selected_Filelist->get_by_idx(0);998 $edited_File = & $selected_Filelist->get_by_idx( 0 );
1029999
1030 // Load meta data AND MAKE SURE IT IS CREATED IN DB:1000 // Load meta data AND MAKE SURE IT IS CREATED IN DB
1031 $edited_File->load_meta( true );1001 $edited_File->load_meta( true );
10321002
1033 // REDIRECT / EXIT1003 // "Extended Identity" section - (avatar selection)
1034 header_redirect( $admin_url.'?ctrl=users&user_ID='.$edited_User->ID );1004 $edited_User->set( 'avatar_ID', $edited_File->ID );
1035 break;1005 $edited_User->dbupdate();
10361006 $Messages->add( T_('User avatar modified.'), 'success' );
1007
1008 // REDIRECT / EXIT
1009 header_redirect( $admin_url.'?ctrl=users&user_ID='.$edited_User->ID );
1010 break;
10371011
1038 case 'link':1012 case 'link':
1039 case 'link_inpost': // In the context of a post1013 case 'link_inpost':
1040 // TODO: We don't need the Filelist, move UP!1014 // In the context of a post
1041 // Link File to Item1015 // Link File to Item
10421016
1043 // Note: we are not modifying any file here, we're just linking it1017 // Note: we are not modifying any file here, we're just linking it. we only need read
1044 // we only need read perm on file, but we'll need write perm on destination object (to be checked below)1018 // perm on file, but we'll need write perm on destination object (to be checked below)
10451019 if( ! isset( $edited_Item ) )
1046 if( ! isset($edited_Item) )1020 {
1047 { // No Item to link to - end link_item mode.1021 // No Item to link to - end link_item mode.
1048 $fm_mode = NULL;1022 $fm_mode = NULL;
1049 break;1023 break;
1050 }1024 }
10511025
1052 // Check item EDIT permissions:1026 // Check item EDIT permissions
1053 $current_User->check_perm( 'item_post!CURSTATUS', 'edit', true, $edited_Item );1027 $current_User->check_perm( 'item_post!CURSTATUS', 'edit', true, $edited_Item );
10541028
1055 // Get the file we want to link:1029 // Get the file we want to link
1056 if( !$selected_Filelist->count() )1030 if( !$selected_Filelist->count() )
1057 {1031 {
1058 $Messages->add( T_('Nothing selected.'), 'error' );1032 $Messages->add( T_('Nothing selected.'), 'error' );
1059 break;1033 break;
1060 }1034 }
1061 $edited_File = & $selected_Filelist->get_by_idx(0);1035 $edited_File = & $selected_Filelist->get_by_idx(0);
10621036
1063 $DB->begin();1037 $DB->begin();
10641038
1065 // Load meta data AND MAKE SURE IT IS CREATED IN DB:1039 // Load meta data AND MAKE SURE IT IS CREATED IN DB
1066 $edited_File->load_meta( true );1040 $edited_File->load_meta( true );
10671041
1068 // Let's make the link!1042 // Let's make the link!
1069 $edited_Link = new Link();1043 $edited_Link = new Link();
1070 $edited_Link->set( 'itm_ID', $edited_Item->ID );1044 $edited_Link->set( 'itm_ID', $edited_Item->ID );
1071 $edited_Link->set( 'file_ID', $edited_File->ID );1045 $edited_Link->set( 'file_ID', $edited_File->ID );
1072 $edited_Link->dbinsert();1046 $edited_Link->dbinsert();
10731047
1074 $DB->commit();1048 $DB->commit();
10751049
1076 $Messages->add( T_('Selected file has been linked to item.'), 'success' );1050 $Messages->add( T_('Selected file has been linked to item.'), 'success' );
10771051
1078 // In case the mode had been closed, reopen it:1052 // In case the mode had been closed, reopen it
1079 $fm_mode = 'link_item';1053 $fm_mode = 'link_item';
10801054
10811055
1082 // REDIRECT / EXIT1056 // REDIRECT / EXIT
1083 if( $action == 'link_inpost' )1057 if( $action == 'link_inpost' )
1084 {1058 {
1085 header_redirect( $admin_url.'?ctrl=items&action=edit_links&mode=iframe&item_ID='.$edited_Item->ID );1059 header_redirect( $admin_url.'?ctrl=items&action=edit_links&mode=iframe&item_ID='.$edited_Item->ID );
1086 }1060 }
1087 else1061 else
1088 {1062 {
1089 header_redirect( regenerate_url( '', '', '', '&' ) );1063 header_redirect( regenerate_url( '', '', '', '&' ) );
1090 }1064 }
1091 break;1065 break;
1092
10931066
1094 case 'unlink':1067 case 'unlink':
1095 // TODO: We don't need the Filelist, move UP!1068 // Unlink File from Item (or other object if extended):
1096 // Unlink File from Item (or other object if extended):1069 // Note: we are not modifying any file here, we're just linking it
10971070 // we only need read perm on file, but we'll need write perm on destination object (to be checked below)
1098 // Note: we are not modifying any file here, we're just linking it1071
1099 // we only need read perm on file, but we'll need write perm on destination object (to be checked below)1072 if( ! isset( $edited_Link ) )
11001073 {
1101 if( !isset( $edited_Link ) )
1102 {
1103 $action = 'list';
1104 break;
1105 }
1106
1107 // get Item (or other object) from Link to check perm
1108 $edited_Item = & $edited_Link->Item;
1109
1110 // Check that we have permission to edit item:
1111 $current_User->check_perm( 'item_post!CURSTATUS', 'edit', true, $edited_Item );
1112
1113 // Delete from DB:
1114 $msg = sprintf( T_('Link from &laquo;%s&raquo; deleted.'), $edited_Link->Item->dget('title') );
1115 $edited_Link->dbdelete( true );
1116 unset( $edited_Link );
1117 forget_param( 'link_ID' );
1118
1119 $Messages->add( $msg, 'success' );
1120 $action = 'list';1074 $action = 'list';
1121 // REDIRECT / EXIT
1122 header_redirect( regenerate_url( '', '', '', '&' ) );
1123 break;1075 break;
11241076 }
1077
1078 // get Item (or other object) from Link to check perm
1079 $edited_Item = & $edited_Link->Item;
1080
1081 // Check that we have permission to edit item:
1082 $current_User->check_perm( 'item_post!CURSTATUS', 'edit', true, $edited_Item );
1083
1084 // Delete from DB
1085 $msg = sprintf( T_('Link from &laquo;%s&raquo; deleted.'), $edited_Link->Item->dget( 'title' ) );
1086 $edited_Link->dbdelete( true );
1087 unset( $edited_Link );
1088 forget_param( 'link_ID' );
1089
1090 $Messages->add( $msg, 'success' );
1091 $action = 'list';
1092 // REDIRECT / EXIT
1093 header_redirect( regenerate_url( '', '', '', '&' ) );
1094 break;
11251095
1126 case 'edit_perms':1096 case 'edit_perms':
1127 // TODO: We don't need the Filelist, move UP!1097 // Edit file or directory permissions:
1128 // Edit file or directory permissions:1098 if( ! $current_User->check_perm( 'files', 'edit' ) )
11291099 {
1130 if( ! $current_User->check_perm( 'files', 'edit' ) )1100 // We do not have permission to edit files
1131 { // We do not have permission to edit files1101 $Messages->add( T_('You have no permission to edit/modify files.'), 'error' );
1132 $Messages->add( T_('You have no permission to edit/modify files.'), 'error' );1102 $action = 'list';
1133 $action = 'list';1103 break;
1134 break;1104 }
1135 }1105
11361106 if( ! $selected_Filelist->count() )
1137 if( ! $selected_Filelist->count() )1107 {
1138 {1108 $Messages->add( T_('Nothing selected.'), 'error' );
1139 $Messages->add( T_('Nothing selected.'), 'error' );1109 $action = 'list';
1140 $action = 'list';1110 break;
1141 break;1111 }
1142 }1112
11431113 param( 'perms', 'array', array() );
11441114 // default value when multiple files are selected
1145 param( 'perms', 'array', array() );1115 param( 'edit_perms_default' );
1146 param( 'edit_perms_default' ); // default value when multiple files are selected1116 // array of file IDs that should be set to default
1147 param( 'use_default_perms', 'array', array() ); // array of file IDs that should be set to default1117 param( 'use_default_perms', 'array', array() );
11481118
1149 if( count( $use_default_perms ) && $edit_perms_default === '' )1119 if( count( $use_default_perms ) && $edit_perms_default === '' )
1150 {1120 {
1151 param_error( 'edit_perms_default', T_('You have to give a default permission!') );1121 param_error( 'edit_perms_default', T_('You have to give a default permission!') );
1152 break;1122 break;
1153 }1123 }
11541124
1155 // form params1125 // form params
1156 $perms_read_readonly = is_windows();1126 $perms_read_readonly = is_windows();
1157 $field_options_read_readonly = array(1127 $field_options_read_readonly = array(
1158 array( 'value' => 444, 'label' => T_('Read-only') ),1128 array( 'value' => 444, 'label' => T_('Read-only') ),
1159 array( 'value' => 666, 'label' => T_('Read and write') ) );1129 array( 'value' => 666, 'label' => T_('Read and write')
1160 $more_than_one_selected_file = ( $selected_Filelist->count() > 1 );1130 ) );
11611131 $more_than_one_selected_file = ( $selected_Filelist->count() > 1 );
1162 if( count( $perms ) || count( $use_default_perms ) )1132
1163 { // New permissions given, change them1133 if( count( $perms ) || count( $use_default_perms ) )
1164 $selected_Filelist->restart();1134 {
1165 while( $l_File = & $selected_Filelist->get_next() )1135 // New permissions given, change them
1166 {1136 $selected_Filelist->restart();
1167 if( in_array( $l_File->get_md5_ID(), $use_default_perms ) )1137 while( $l_File = & $selected_Filelist->get_next() )
1168 { // use default1138 {
1169 $chmod = $edit_perms_default;1139 if( in_array( $l_File->get_md5_ID(), $use_default_perms ) )
1170 }1140 {
1171 elseif( !isset($perms[ $l_File->get_md5_ID() ]) )1141 // use default
1172 { // happens for an empty text input or when no radio option is selected1142 $chmod = $edit_perms_default;
1173 $Messages->add( sprintf( T_('Permissions for &laquo;%s&raquo; have not been changed.'), $l_File->dget('name') ), 'note' );1143 }
1174 continue;1144 elseif( ! isset( $perms[$l_File->get_md5_ID()] ) )
1175 }1145 {
1176 else1146 // happens for an empty text input or when no radio option is selected
1177 { // provided for this file1147 $Messages->add( sprintf( T_('Permissions for &laquo;%s&raquo; have not been changed.'), $l_File->dget( 'name' ) ), 'note' );
1178 $chmod = $perms[ $l_File->get_md5_ID() ];1148 continue;
1179 }1149 }
11801150 else
1181 $oldperms = $l_File->get_perms( 'raw' );1151 {
1182 $newperms = $l_File->chmod( octdec( $chmod ) );1152 // provided for this file
11831153 $chmod = $perms[$l_File->get_md5_ID()];
1184 if( $newperms === false )1154 }
1185 {1155
1186 $Messages->add( sprintf( T_('Failed to set permissions on &laquo;%s&raquo; to &laquo;%s&raquo;.'), $l_File->dget('name'), $chmod ), 'error' );1156 $oldperms = $l_File->get_perms( 'raw' );
1187 }1157 $newperms = $l_File->chmod( octdec( $chmod ) );
1188 else1158
1189 {1159 if( $newperms === false )
1190 // Success, remove the file from the list of selected files:1160 {
1191 $selected_Filelist->remove( $l_File );1161 $Messages->add( sprintf( T_('Failed to set permissions on &laquo;%s&raquo; to &laquo;%s&raquo;.'), $l_File->dget( 'name' ), $chmod ), 'error' );
11921162 }
1193 if( $newperms === $oldperms )1163 else
1194 {1164 {
1195 $Messages->add( sprintf( T_('Permissions for &laquo;%s&raquo; have not been changed.'), $l_File->dget('name') ), 'note' );1165 // Success, remove the file from the list of selected files
1196 }1166 $selected_Filelist->remove( $l_File );
1197 else1167
1198 {1168 if( $newperms === $oldperms )
1199 $Messages->add( sprintf( T_('Permissions for &laquo;%s&raquo; changed to &laquo;%s&raquo;.'), $l_File->dget('name'), $l_File->get_perms() ), 'success' );1169 {
1200 }1170 $Messages->add( sprintf( T_('Permissions for &laquo;%s&raquo; have not been changed.'), $l_File->dget( 'name' ) ), 'note' );
1201 }1171 }
1202 }1172 else
1203 }1173 {
12041174 $Messages->add( sprintf( T_('Permissions for &laquo;%s&raquo; changed to &laquo;%s&raquo;.'), $l_File->dget( 'name' ), $l_File->get_perms() ), 'success' );
1205 if( !$selected_Filelist->count() )1175 }
1206 { // No file left selected... (everything worked fine)1176 }
1207 $action = 'list';1177 }
1208 }1178 }
1209 break;1179
1180 if( !$selected_Filelist->count() )
1181 {
1182 // No file left selected ... (everything worked fine)
1183 $action = 'list';
1184 }
1185 break;
1210}1186}
12111187
1212// Prepare for modes:1188// Prepare for modes
1213switch( $fm_mode )1189switch( $fm_mode )
1214{1190{
1215 case 'file_copy':1191 case 'file_copy':
1216 case 'file_move':1192 case 'file_move':
1217 // ------------------------1193 // copy/move a file
1218 // copy/move a file:1194
1219 // ------------------------1195 /*
1220 /*1196 TODO: On error notes use prefixed names, if the roots differ.
1221 * fplanque>> This whole thing is flawed:1197 Something like $fm_Filelist->get_names_realtive_to( $a_File, $b_File, $root_type, $root_ID, $rel_path )
1222 * 1) only geeks can possibly like to use the same interface for renaming, moving and copying1198 that returns an array containing the name of $a_File and $b_File relative to the Root path given as
1223 * 2) even the geeky unix commands won't pretend copying and moving are the same thing. They are not!1199 param 3, 4, 5.
1224 * Only moving and renaming are similar, and again FOR GEEKS ONLY.1200 This would allow to say "Copied «users/admin/test_me.jpg» to «test_me.jpg»." rather than just
1225 * 3) The way this works it breaks the File meta data (I'm working on it).1201 "Copied «test_me.jpg» to «test_me.jpg».".
1226 * 4) For Move and Copy, this should use a "destination directory tree" on the right (same as for upload)1202 // fp>> I don't really understand this (probably missing a verb) but I do think that extending the Fileman object is not the right direction to go on the long term
1227 * 5) Given all the reasons above copy, move and rename should be clearly separated into 3 different interfaces.1203 // blueyed>> Tried to make it clearer. If it wasn't a Filemanager method, it has to be a function or
1228 *1204 // a method of the File class. IMHO it should be a method of the (to be killed) Filemanager object.
1229 * blueyed>> it was never meant to only use a single interface. The original mode1205 // fp>> Okay. It should *definitely* be a method of the File object and we should ask for ONE file at a time. Any question about 'where is the file?' (what/where/when/who, etc) should be asked to the File object itself.
1230 * 'file_cmr' was just a mode to handle it internally easier/more central.1206 */
1231 * 'copy' is just 'move and keep the source', while 'rename' is 'move in the same dir'1207
1232 *1208 if( ! $current_User->check_perm( 'files', 'edit' ) )
1233 */1209 {
12341210 // We do not have permission to edit files
1235 /*1211 $Messages->add( T_('You have no permission to edit/modify files.'), 'error' );
1236 TODO: On error notes use prefixed names, if the roots differ.1212 $fm_mode = NULL;
1237 Something like $fm_Filelist->get_names_realtive_to( $a_File, $b_File, $root_type, $root_ID, $rel_path )1213 break;
1238 that returns an array containing the name of $a_File and $b_File relative to the Root path given as1214 }
1239 param 3, 4, 5.1215
1240 This would allow to say "Copied «users/admin/test_me.jpg» to «test_me.jpg»." rather than just1216 // Get the source list
1241 "Copied «test_me.jpg» to «test_me.jpg».".1217 if( $fm_sources = param( 'fm_sources', 'array', array(), true ) )
1242 // fp>> I don't really understand this (probably missing a verb) but I do think that extending the Fileman object is not the right direction to go on the long term1218 {
1243 // blueyed>> Tried to make it clearer. If it wasn't a Filemanager method, it has to be a function or1219 $fm_sources_root = param( 'fm_sources_root', 'string', '', true );
1244 // a method of the File class. IMHO it should be a method of the (to be killed) Filemanager object.1220 $sources_Root = & $FileRootCache->get_by_ID( $fm_sources_root );
1245 // fp>> Okay. It should *definitely* be a method of the File object and we should ask for ONE file at a time. Any question about 'where is the file?' (what/where/when/who, etc) should be asked to the File object itself.1221
1246 */1222 if( $sources_Root )
12471223 {
1248 if( ! $current_User->check_perm( 'files', 'edit' ) )1224 // instantiate the source list for the selected sources
1249 { // We do not have permission to edit files1225 $fm_source_Filelist = new Filelist( $sources_Root );
1250 $Messages->add( T_('You have no permission to edit/modify files.'), 'error' );1226 }
1251 $fm_mode = NULL;1227 else
1252 break;1228 {
1253 }1229 // Fallback: source files are considered to be in the current root
12541230 $fm_source_Filelist = new Filelist( $fm_Filelist->get_FileRoot() );
1255 // Get the source list1231 }
1256 if( $fm_sources = param( 'fm_sources', 'array', array(), true ) )1232
1257 {1233 if( $fm_source_Filelist )
1258 $fm_sources_root = param( 'fm_sources_root', 'string', '', true );1234 {
12591235 foreach( $fm_sources as $l_source_path )
1260 $sources_Root = & $FileRootCache->get_by_ID( $fm_sources_root );1236 {
12611237 $fm_source_Filelist->add_by_subpath( urldecode( $l_source_path ), true );
1262 if( $sources_Root )1238 }
1263 { // instantiate the source list for the selected sources1239 }
1264 $fm_source_Filelist = new Filelist( $sources_Root );1240 else
1265 }1241 {
1266 else1242 // Without SourceList there's no mode
1267 { // Fallback: source files are considered to be in the current root1243 $fm_mode = false;
1268 $fm_source_Filelist = new Filelist( $fm_Filelist->get_FileRoot() );1244 }
1269 $Debuglog->add( 'SourceList without explicit root!', 'error' );1245 }
1270 }1246 else
12711247 {
1272 if( $fm_source_Filelist )1248 $fm_source_Filelist = false;
1273 {1249 $fm_sources = NULL;
1274 // TODO: should fail for non-existant sources, or sources where no read-perm1250 $fm_sources_root = NULL;
1275 foreach( $fm_sources as $l_source_path )1251 }
1276 {1252
1277 $fm_source_Filelist->add_by_subpath( urldecode($l_source_path), true );1253 if( ! $fm_source_Filelist || ! $fm_source_Filelist->count() )
1278 }1254 {
1279 }1255 $Messages->add( T_('No source files!'), 'error' );
1280 else1256 $fm_mode = NULL;
1281 { // Without SourceList there's no mode1257 break;
1282 $fm_mode = false;1258 }
1283 }1259
1284 }1260 param( 'confirm', 'integer', 0 );
1285 else1261 param( 'new_names', 'array', array() );
1286 {1262 param( 'overwrite', 'array', array() );
1287 $fm_source_Filelist = false;1263
1288 $fm_sources = NULL;1264 // Check params for each file to rename
1289 $fm_sources_root = NULL;1265 while( $loop_src_File = & $fm_source_Filelist->get_next() )
1290 }1266 {
12911267 if( ! $loop_src_File->exists() )
1292 if( ! $fm_source_Filelist || ! $fm_source_Filelist->count() )1268 {
1293 {1269 // this can happen on reloading the page
1294 $Messages->add( T_('No source files!'), 'error' );1270 $fm_source_Filelist->remove( $loop_src_File );
1295 $fm_mode = NULL;1271 continue;
1296 break;1272 }
1297 }1273 if( ! isset( $new_names[$loop_src_File->get_md5_ID()] ) )
12981274 {
1299 param( 'confirm', 'integer', 0 );1275 // We have not yet provided a name to rename to...
1300 param( 'new_names', 'array', array() );1276 $confirm = 0;
1301 param( 'overwrite', 'array', array() );1277 $new_names[$loop_src_File->get_md5_ID()] = $loop_src_File->get( 'name' );
13021278 continue;
1303 // Check params for each file to rename:1279 }
1280
1281 // Check if provided name is okay
1282 $new_names[$loop_src_File->get_md5_ID()] = trim( strip_tags( $new_names[$loop_src_File->get_md5_ID()] ) );
1283
1284 if( !$loop_src_File->is_dir() )
1285 {
1286 if( $error_filename = validate_filename( $new_names[$loop_src_File->get_md5_ID()] ) )
1287 {
1288 // Not a file name or not an allowed extension
1289 $confirm = 0;
1290 $Messages->add( $error_filename, 'error' );
1291 continue;
1292 }
1293 }
1294 elseif( $error_dirname = validate_dirname( $new_names[$loop_src_File->get_md5_ID()] ) )
1295 {
1296 // Not a directory name
1297 $confirm = 0;
1298 $Messages->add( $error_dirname, 'error' );
1299 continue;
1300 }
1301
1302 // Check if destination file exists
1303 $FileCache = & get_Cache( 'FileCache' );
1304 if( ( $dest_File = & $FileCache->get_by_root_and_path( $fm_Filelist->get_root_type(), $fm_Filelist->get_root_ID(), $fm_Filelist->get_rds_list_path().$new_names[$loop_src_File->get_md5_ID()] ) )
1305 && $dest_File->exists() )
1306 {
1307 // Target exists
1308 if( $dest_File === $loop_src_File )
1309 {
1310 param_error( 'new_names['.$loop_src_File->get_md5_ID().']', T_('Source and target files are the same. Please choose another name or directory.') );
1311 $confirm = 0;
1312 continue;
1313 }
1314
1315 if( ! isset( $overwrite[$loop_src_File->get_md5_ID()] ) )
1316 {
1317 // We have not yet asked to overwrite
1318 param_error( 'new_names['.$loop_src_File->get_md5_ID().']', sprintf( T_('The file &laquo;%s&raquo; already exists.'), $dest_File->get_rdfp_rel_path() ) );
1319 $overwrite[$loop_src_File->get_md5_ID()] = 0;
1320 $confirm = 0;
1321 continue;
1322 }
1323
1324 // We have asked to overwite...
1325 if( $fm_mode == 'file_copy' )
1326 {
1327 // We are making a copy: no problem, we'll recycle the file ID anyway
1328 continue;
1329 }
1330
1331 // We are moving, we'll need to unlink the target file and drop it's meta data
1332 // Check if there are delete restrictions on this file:
1333 $dest_File->check_relations( 'delete_restrictions' );
1334
1335 if( $Messages->count('restrict') )
1336 {
1337 // There are restrictions
1338 param_error( 'new_names['.$loop_src_File->get_md5_ID().']', sprintf( T_('Cannot overwrite the file &laquo;%s&raquo; because of the following relations'), $dest_File->get_rdfp_rel_path() ) );
1339
1340 $confirm = 0;
1341 break; // stop whole file list processing
1342 }
1343 }
1344 }
1345
1346 if( $confirm && $fm_source_Filelist->count() )
1347 {
1348 // Copy/move is confirmed (and we still have files to copy/move), let's proceed
1349 // Loop through files:
1350 $fm_source_Filelist->restart();
1304 while( $loop_src_File = & $fm_source_Filelist->get_next() )1351 while( $loop_src_File = & $fm_source_Filelist->get_next() )
1305 {1352 {
1306 if( ! $loop_src_File->exists() )1353 // Get a pointer on dest file
1307 { // this can happen on reloading the page
1308 $fm_source_Filelist->remove($loop_src_File);
1309 continue;
1310 }
1311 if( ! isset( $new_names[$loop_src_File->get_md5_ID()] ) )
1312 { // We have not yet provided a name to rename to...
1313 $confirm = 0;
1314 $new_names[$loop_src_File->get_md5_ID()] = $loop_src_File->get('name');
1315 continue;
1316 }
1317
1318 // Check if provided name is okay:
1319 $new_names[$loop_src_File->get_md5_ID()] = trim(strip_tags($new_names[$loop_src_File->get_md5_ID()]));
1320
1321 if( !$loop_src_File->is_dir() )
1322 {
1323 if( $error_filename = validate_filename( $new_names[$loop_src_File->get_md5_ID()] ) )
1324 { // Not a file name or not an allowed extension
1325 $confirm = 0;
1326 $Messages->add( $error_filename , 'error' );
1327 continue;
1328 }
1329 }
1330 elseif( $error_dirname = validate_dirname( $new_names[$loop_src_File->get_md5_ID()] ) )
1331 { // Not a directory name
1332 $confirm = 0;
1333 $Messages->add( $error_dirname, 'error' );
1334 continue;
1335 }
1336
1337 // Check if destination file exists:
1338 $FileCache = & get_Cache( 'FileCache' );1354 $FileCache = & get_Cache( 'FileCache' );
1339 if( ($dest_File = & $FileCache->get_by_root_and_path( $fm_Filelist->get_root_type(), $fm_Filelist->get_root_ID(), $fm_Filelist->get_rds_list_path().$new_names[$loop_src_File->get_md5_ID()] ))1355 $dest_File = & $FileCache->get_by_root_and_path( $fm_Filelist->get_root_type(), $fm_Filelist->get_root_ID(), $fm_Filelist->get_rds_list_path().$new_names[$loop_src_File->get_md5_ID()] );
1340 && $dest_File->exists() )1356
1341 { // Target exists1357 if( $fm_mode == 'file_copy' )
1342 if( $dest_File === $loop_src_File )1358 {
1343 {1359 // COPY
1344 param_error( 'new_names['.$loop_src_File->get_md5_ID().']', T_('Source and target files are the same. Please choose another name or directory.') );1360
1345 $confirm = 0;1361 // Do the copy
1346 continue;1362 if( $loop_src_File->copy_to( $dest_File ) )
1347 }1363 {
13481364 // Success
1349 if( ! isset( $overwrite[$loop_src_File->get_md5_ID()] ) )1365 $Messages->add( sprintf( T_('Copied &laquo;%s&raquo; to &laquo;%s&raquo;.'),
1350 { // We have not yet asked to overwrite:1366 $loop_src_File->get_rdfp_rel_path(), $dest_File->get_rdfp_rel_path() ), 'success' );
1351 param_error( 'new_names['.$loop_src_File->get_md5_ID().']', sprintf( T_('The file &laquo;%s&raquo; already exists.'), $dest_File->get_rdfp_rel_path() ) );1367
1352 $overwrite[$loop_src_File->get_md5_ID()] = 0;1368 if( $fm_Filelist->contains( $dest_File ) === false )
1353 $confirm = 0;1369 {
1354 continue;1370 $fm_Filelist->add( $dest_File );
1355 }1371 }
13561372 }
1357 // We have asked to overwite...1373 else
1358 if( $fm_mode == 'file_copy' )1374 {
1359 { // We are making a copy: no problem, we'll recycle the file ID anyway.1375 // Failure
1360 continue;1376 param_error( 'new_names['.$loop_src_File->get_md5_ID().']', sprintf( T_('Could not copy &laquo;%s&raquo; to &laquo;%s&raquo;.'),
1361 }1377 $loop_src_File->get_rdfp_rel_path(), $dest_File->get_rdfp_rel_path() ) );
13621378 }
1363 // We are moving, we'll need to unlink the target file and drop it's meta data:1379 }
1364 // Check if there are delete restrictions on this file:1380 elseif( $fm_mode == 'file_move' )
1365 $dest_File->check_relations( 'delete_restrictions' );1381 {
13661382 // MOVE
1367 if( $Messages->count('restrict') )1383 // NOTE: DB integrity is handled by the File object itself
1368 { // There are restrictions:1384 $DB->begin();
1369 // TODO: work on a better output display here...1385
1370 param_error( 'new_names['.$loop_src_File->get_md5_ID().']', sprintf( T_('Cannot overwrite the file &laquo;%s&raquo; because of the following relations'), $dest_File->get_rdfp_rel_path() ) );1386 if( isset( $overwrite[$loop_src_File->get_md5_ID()] )
13711387 && $overwrite[$loop_src_File->get_md5_ID()] )
1372 $confirm = 0;1388 {
1373 break; // stop whole file list processing1389 // We want to overwrite, let's unlink the old file
1374 }1390 if( ! $dest_File->unlink() )
1375 }1391 {
1376 }1392 // Unlink failed
13771393 $DB->rollback();
1378 if( $confirm && $fm_source_Filelist->count() )1394
1379 { // Copy/move is confirmed (and we still have files to copy/move), let's proceed:1395 $Messages->add( sprintf( ( $dest_File->is_dir() ? T_('Could not delete the directory &laquo;%s&raquo; (not empty?).') : T_('Could not delete the file &laquo;%s&raquo;.') ), $dest_File->dget( 'name' ) ), 'error' );
13801396
1381 // Loop through files:1397 // Move on to next file
1382 $fm_source_Filelist->restart();1398 continue;
1383 while( $loop_src_File = & $fm_source_Filelist->get_next() )1399 }
1384 {1400 }
1385 // Get a pointer on dest file1401
1386 $FileCache = & get_Cache( 'FileCache' );1402 // Do the move
1387 $dest_File = & $FileCache->get_by_root_and_path( $fm_Filelist->get_root_type(), $fm_Filelist->get_root_ID(), $fm_Filelist->get_rds_list_path().$new_names[$loop_src_File->get_md5_ID()] );1403 $rdfp_oldpath = $loop_src_File->get_rdfp_rel_path();
13881404 $rdfp_newpath = $fm_Filelist->get_rds_list_path().$new_names[$loop_src_File->get_md5_ID()];
1389 if( $fm_mode == 'file_copy' )1405
1390 { // COPY1406 if( $loop_src_File->move_to( $fm_Filelist->get_root_type(), $fm_Filelist->get_root_ID(), $rdfp_newpath ) )
13911407 {
1392 // Do the copy1408 // successfully moved
1393 if( $loop_src_File->copy_to( $dest_File ) )1409 $Messages->add( sprintf( T_('Moved &laquo;%s&raquo; to &laquo;%s&raquo;.'), $rdfp_oldpath, $rdfp_newpath ), 'success' );
1394 { // Success:1410
1395 $Messages->add( sprintf( T_('Copied &laquo;%s&raquo; to &laquo;%s&raquo;.'),1411 // We may have moved in same dir, update caches
1396 $loop_src_File->get_rdfp_rel_path(), $dest_File->get_rdfp_rel_path() ), 'success' );1412 $fm_Filelist->update_caches();
13971413 // We remove the file from the source list, after refreshing the cache
1398 if( $fm_Filelist->contains( $dest_File ) === false )1414 $fm_source_Filelist->update_caches();
1399 {1415 $fm_source_Filelist->remove( $loop_src_File );
1400 $fm_Filelist->add( $dest_File );1416
1401 }1417 if( $fm_Filelist->contains( $loop_src_File ) === false )
1402 }1418 {
1403 else1419 // File not in filelist (expected if not same dir)
1404 { // Failure:1420 $fm_Filelist->add( $loop_src_File );
1405 param_error( 'new_names['.$loop_src_File->get_md5_ID().']', sprintf( T_('Could not copy &laquo;%s&raquo; to &laquo;%s&raquo;.'),1421 }
1406 $loop_src_File->get_rdfp_rel_path(), $dest_File->get_rdfp_rel_path() ) );1422 }
1407 }1423 else
1408 }1424 {
1409 elseif( $fm_mode == 'file_move' )1425 // move failed
1410 { // MOVE1426 param_error( 'new_names['.$loop_src_File->get_md5_ID().']', sprintf( T_('Could not move &laquo;%s&raquo; to &laquo;%s&raquo;.'), $rdfp_oldpath, $rdfp_newpath ) );
1411 // NOTE: DB integrity is handled by the File object itself1427 // Note: we do not rollback, since unlinking is already done on disk :'(
1412 $DB->begin();1428 }
14131429
1414 if( isset( $overwrite[$loop_src_File->get_md5_ID()] )1430 $DB->commit();
1415 && $overwrite[$loop_src_File->get_md5_ID()] )1431 }
1416 { // We want to overwrite, let's unlink the old file:1432 else debug_die( 'Unhandled file copy/move mode' );
1417 if( ! $dest_File->unlink() )1433 }
1418 { // Unlink failed:1434
1419 $DB->rollback();1435 // EXIT MODE
14201436 $fm_mode = NULL;
1421 $Messages->add( sprintf( ( $dest_File->is_dir() ? T_('Could not delete the directory &laquo;%s&raquo; (not empty?).') : T_('Could not delete the file &laquo;%s&raquo;.') ), $dest_File->dget('name') ), 'error' );1437 }
14221438 break;
1423 // Move on to next file:
1424 continue;
1425 }
1426 }
1427
1428 // Do the move:
1429 $rdfp_oldpath = $loop_src_File->get_rdfp_rel_path();
1430 $rdfp_newpath = $fm_Filelist->get_rds_list_path().$new_names[$loop_src_File->get_md5_ID()];
1431
1432 if( $loop_src_File->move_to( $fm_Filelist->get_root_type(), $fm_Filelist->get_root_ID(), $rdfp_newpath ) )
1433 { // successfully moved
1434 $Messages->add( sprintf( T_('Moved &laquo;%s&raquo; to &laquo;%s&raquo;.'), $rdfp_oldpath, $rdfp_newpath ), 'success' );
1435
1436 // We may have moved in same dir, update caches:
1437 $fm_Filelist->update_caches();
1438 // We remove the file from the source list, after refreshing the cache
1439 $fm_source_Filelist->update_caches();
1440 $fm_source_Filelist->remove( $loop_src_File );
1441
1442 if( $fm_Filelist->contains( $loop_src_File ) === false )
1443 { // File not in filelist (expected if not same dir)
1444 $fm_Filelist->add( $loop_src_File );
1445 }
1446 }
1447 else
1448 { // move failed
1449 param_error( 'new_names['.$loop_src_File->get_md5_ID().']', sprintf( T_('Could not move &laquo;%s&raquo; to &laquo;%s&raquo;.'), $rdfp_oldpath, $rdfp_newpath ) );
1450 // Note: we do not rollback, since unlinking is already done on disk :'(
1451 }
1452
1453 $DB->commit();
1454 }
1455 else debug_die( 'Unhandled file copy/move mode' );
1456 }
1457
1458 // EXIT MODE:
1459 $fm_mode = NULL;
1460 }
1461 break;
14621439
1463 case 'link_item':1440 case 'link_item':
1464 // We want to link file(s) to an item:1441 // We want to link file(s) to an item
1465 // TODO: maybe this should not be a mode and maybe we should handle linking as soon as we have an $edited_Item ...1442 if( ! isset( $edited_Item ) )
1466 if( !isset($edited_Item) )1443 {
1467 { // No Item to link to...1444 // No Item to link to...
1468 $fm_mode = NULL;1445 $fm_mode = NULL;
1469 break;
1470 }
1471
1472 // TODO: check EDIT permissions!
1473 break;1446 break;
1447 }
1448 break;
14741449
1475}1450}
14761451
1477// Update sub-menu:1452// Update sub-menu
1478if( $current_User->check_perm( 'files', 'add' ) )1453if( $current_User->check_perm( 'files', 'add' ) )
1479{ // Permission to upload and we are not in a popup window (no subtabs needed otherwise)1454{
1480 $AdminUI->add_menu_entries(1455 // Permission to upload and we are not in a popup window (no subtabs needed otherwise)
1481 'files',1456 $AdminUI->add_menu_entries( 'files', array(
1482 array(
1483 'browse' => array(1457 'browse' => array(
1484 'text' => T_('Browse'),1458 'text' => T_('Browse'),
1485 'href' => regenerate_url( 'ctrl', 'ctrl=files' ) ),1459 'href' => regenerate_url( 'ctrl', 'ctrl=files' ) ),
@@ -1490,10 +1464,9 @@
1490 );1464 );
1491}1465}
14921466
1493// Display <html><head>...</head> section! (Note: should be done early if actions do not redirect)1467// Display <html><head>...</head> section (should be done early if actions do not redirect)
1494$AdminUI->disp_html_head();1468$AdminUI->disp_html_head();
14951469// Display title, menu, messages, etc... (messages MUST be displayed AFTER the actions)
1496// Display title, menu, messages, etc. (Note: messages MUST be displayed AFTER the actions)
1497$AdminUI->disp_body_top();1470$AdminUI->disp_body_top();
14981471
1499// Display reload-icon in the opener window if we're a popup in the same CWD and the1472// Display reload-icon in the opener window if we're a popup in the same CWD and the
@@ -1505,7 +1478,7 @@
1505 && opener.document.FilesForm1478 && opener.document.FilesForm
1506 && typeof(opener.document.FilesForm.md5_filelist.value) != 'undefined'1479 && typeof(opener.document.FilesForm.md5_filelist.value) != 'undefined'
1507 && typeof(opener.document.FilesForm.md5_cwd.value) != 'undefined'1480 && typeof(opener.document.FilesForm.md5_cwd.value) != 'undefined'
1508 && opener.document.FilesForm.md5_cwd.value == '<?php echo md5($fm_Filelist->get_ads_list_path()); ?>'1481 && opener.document.FilesForm.md5_cwd.value == '<?php echo md5( $fm_Filelist->get_ads_list_path() ); ?>'
1509 )1482 )
1510 {1483 {
1511 opener.document.getElementById( 'fm_reloadhint' ).style.display =1484 opener.document.getElementById( 'fm_reloadhint' ).style.display =
@@ -1516,104 +1489,97 @@
1516 // -->1489 // -->
1517</script>1490</script>
1518<?php1491<?php
15191492// Begin payload block
1520$AdminUI->disp_payload_begin();1493$AdminUI->disp_payload_begin();
15211494
1522// Display payload:1495// Display payload
1523if( !empty($action ) && $action != 'list' && $action != 'nil' )1496if( ! empty( $action ) && $action != 'list' && $action != 'nil' )
1524{1497{
15251498
1526 // Action displays:1499 // Action displays:
1527 switch( $action )1500 switch( $action )
1528 {1501 {
1529 case 'rename':1502 case 'rename':
1530 // Rename files dialog:1503 // Rename files dialog:
1531 $AdminUI->disp_view( 'files/views/_file_rename.form.php' );1504 $AdminUI->disp_view( 'files/views/_file_rename.form.php' );
1532 break;1505 break;
15331506
1534 case 'delete':1507 case 'delete':
1535 // Delete file(s). We arrive here either if not confirmed or in case of error(s).1508 // Delete file(s). We arrive here either if not confirmed or in case of error(s).
1536 $AdminUI->disp_view( 'files/views/_file_delete.form.php' );1509 $AdminUI->disp_view( 'files/views/_file_delete.form.php' );
1537 break;1510 break;
15381511
1539 case 'download':1512 case 'download':
1540 $AdminUI->disp_view( 'files/views/_file_download.form.php' );1513 $AdminUI->disp_view( 'files/views/_file_download.form.php' );
1541 break;1514 break;
15421515
1543 case 'edit_perms':1516 case 'edit_perms':
1544 // Filesystem permissions for specific files1517 // Filesystem permissions for specific files
1545 $AdminUI->disp_view( 'files/views/_file_permissions.form.php' );1518 $AdminUI->disp_view( 'files/views/_file_permissions.form.php' );
1546 break;1519 break;
15471520
1548 case 'edit_file':1521 case 'edit_file':
1549 // File Edit dialog:1522 // File Edit dialog:
1550 $AdminUI->disp_view( 'files/views/_file_edit.form.php' );1523 $AdminUI->disp_view( 'files/views/_file_edit.form.php' );
1551 break;1524 break;
15521525
1553 case 'edit_properties':1526 case 'edit_properties':
1554 // File properties (Meta data) dialog:1527 // File properties (Meta data) dialog:
1555 $AdminUI->disp_view( 'files/views/_file_properties.form.php' );1528 $AdminUI->disp_view( 'files/views/_file_properties.form.php' );
1556 break;1529 break;
15571530
1558 case 'edit_settings':1531 case 'edit_settings':
1559 // Display settings dialog:1532 // Display settings dialog:
1560 $AdminUI->disp_view( 'files/views/_file_browse_set.form.php' );1533 $AdminUI->disp_view( 'files/views/_file_browse_set.form.php' );
1561 break;1534 break;
15621535
1563 case 'download':1536 case 'download':
1564 // Deferred action message:1537 // Deferred action message:
1565 if( isset($action_title) )1538 if( isset( $action_title ) )
1566 {1539 {
1567 echo "\n<h2>$action_title</h2>\n";1540 echo "\n<h2>$action_title</h2>\n";
1568 }1541 }
15691542
1570 if( isset($action_msg) )1543 if( isset( $action_msg ) )
1571 {1544 {
1572 echo $action_msg;1545 echo $action_msg;
15731546
1574 if( isset( $js_focus ) )1547 if( isset( $js_focus ) )
1575 { // we want to auto-focus a field1548 {
1576 echo '1549 // we want to auto-focus a field
1577 <script type="text/javascript">1550 echo '
1578 <!--1551 <script type="text/javascript">
1579 '.$js_focus.'.focus();1552 <!--
1580 // -->1553 '.$js_focus.'.focus();
1581 </script>';1554 // -->
1582 }1555 </script>';
1583 }1556 }
1557 }
1584 }1558 }
1585}1559}
15861560
15871561// Diplay mode payload
1588/*
1589 * Diplay mode payload:
1590 */
1591switch( $fm_mode )1562switch( $fm_mode )
1592{1563{
1593 case 'file_copy':1564 case 'file_copy':
1594 case 'file_move':1565 case 'file_move':
1595 // CMR dialog:1566 // CMR dialog:
1596 $AdminUI->disp_view( 'files/views/_file_copy_move.form.php' );1567 $AdminUI->disp_view( 'files/views/_file_copy_move.form.php' );
1597 break;1568 break;
15981569
1599 case 'link_item':1570 case 'link_item':
1600 // Links dialog:1571 // Links dialog:
1601 $AdminUI->disp_view( 'files/views/_file_links.view.php' );1572 $AdminUI->disp_view( 'files/views/_file_links.view.php' );
1602 break;1573 break;
1603}1574}
16041575
16051576// Browsing interface
1606// -------------------1577// Display VIEW
1607// Browsing interface:
1608// -------------------
1609// Display VIEW:
1610$AdminUI->disp_view( 'files/views/_file_browse.view.php' );1578$AdminUI->disp_view( 'files/views/_file_browse.view.php' );
16111579
16121580// End payload block
1613// End payload block:
1614$AdminUI->disp_payload_end();1581$AdminUI->disp_payload_end();
16151582// Display body bottom, debug info, close </html>
1616// Display body bottom, debug info and close </html>:
1617$AdminUI->disp_global_footer();1583$AdminUI->disp_global_footer();
16181584
1619?>1585?>
16201586
=== modified file 'qp_inc/plugins/_plugin.class.php'
--- qp_inc/plugins/_plugin.class.php 2011-11-21 17:17:22 +0000
+++ qp_inc/plugins/_plugin.class.php 2013-03-05 23:36:23 +0000
@@ -1,59 +1,38 @@
1<?php1<?php
2/**2/**
3 * This file implements the abstract {@link Plugin} class.3 * This file implements the Plugin class
4 *4 *
5 * This file is part of Quam Plures - {@link http://quamplures.net/}5 * Real plugins should be derived from this class.
6 * See also {@link https://launchpad.net/quam-plures}.6 *
7 *7 * @todo (1111): var $code needs to be checked for duplicity upon installation and a note thrown
8 * @copyright Copyright (c) 2011 by {@link http://1912webworks.com/ Ed Bennett}8 * to the installing user indicating a potential conflict ... if it isn't already checked ;)
9 * @copyright (c) 2009 - 2011 by the Quam Plures developers - {@link http://quamplures.net/}9 * @todo (1111): var $group needs to be an enum with "other" as the default. There is no need
10 * @copyright (c)2003-2009 by Francois PLANQUE - {@link http://fplanque.net/}10 * for a plugin author to jack up the plugins display page with their own group name!
11 * Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.11 * @todo (1111): var $priority needs to not apply to "install widget". Actually, it needs to not
12 *12 * apply to everything except rendering ... and it needs a rename to $render_priority
13 * {@internal License choice
14 * - If you have received this file as part of a package, please find the license.txt file in
15 * the same folder or the closest folder above for complete license terms.
16 * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
17 * then you must choose one of the following licenses before using the file:
18 * - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
19 * - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
20 * }}
21 *
22 * {@internal Open Source relicensing agreement:
23 * Daniel HAHLER grants Francois PLANQUE the right to license
24 * Daniel HAHLER's contributions to this file and the b2evolution project
25 * under any OSI approved OSS license (http://www.opensource.org/licenses/).
26 * }}
27 *
28 * @todo Add links to pages in the manual, once they are "clean"/tiny
29 *
30 * {@internal Below is a list of authors who have contributed to design/coding of this file: }}
31 * @author {@link http://wonderwinds.com/ Ed Bennett}13 * @author {@link http://wonderwinds.com/ Ed Bennett}
32 * @author fplanque: Francois PLANQUE - {@link http://fplanque.net/}14 * @author {@link http://daniel.hahler.de/ Daniel HAHLER}
33 * @author blueyed: Daniel HAHLER15 * @author {@link http://fplanque.net/ Francois PLANQUE}
34 *16 * @copyright (c) 2009 by {@link http://quamplures.net/ the Quam Plures project}
17 * @license http://www.gnu.org/licenses/gpl.txt GNU General Public License v3
35 * @package plugins18 * @package plugins
36 */19 */
37if( !defined('QP_MAIN_INIT') ) die( 'Please, do not access this page directly.' );20if(!defined('QP_MAIN_INIT')) die('fail');
38
3921
40/**22/**
41 * Plugin Class23 * Plugin class
42 *24 *
43 * Real plugins should be derived from this class.25 * Real plugins should be derived from this class.
44 *
45 * @abstract
46 *
47 * @package plugins26 * @package plugins
48 */27 */
49class Plugin28class Plugin
50{29{
51 /**30 /**
52 * If this is a rendering plugin, when should rendering apply? This is the31 * If this is a rendering plugin, when should rendering apply?
53 * default value for the plugin and can be overriden in the Plugins
54 * administration for plugins that provide rendering events.
55 *32 *
56 * The actual value for the plugin gets stored in T_plugins.plug_apply_rendering.33 * This is the default value for the plugin and can be overriden in the Plugin's
34 * administration for plugins that provide rendering events. The actual value for
35 * the plugin gets stored in T_plugins=>plug_apply_rendering.
57 *36 *
58 * Possible values:37 * Possible values:
59 * - 'stealth': gets always used, but not displayed as option38 * - 'stealth': gets always used, but not displayed as option
@@ -62,241 +41,191 @@
62 * - 'opt-in': disabled by default41 * - 'opt-in': disabled by default
63 * - 'lazy': checkbox gets displayed, but is disabled42 * - 'lazy': checkbox gets displayed, but is disabled
64 * - 'never': cannot get used as a renderer43 * - 'never': cannot get used as a renderer
65 *44 * @var string ENUM( 'stealth', 'always', 'opt-out', 'opt-in', 'lazy', 'never' ) DEFAULT 'never'
66 * @todo (legacy): blueyed>> IMHO we would need another value, which is the same as "lazy", but does not display a checkbox, which is useful for Plugins that add themselves as renderers on Item update
67 *
68 * @var string
69 */45 */
70 var $apply_rendering = 'never';46 var $apply_rendering = 'never';
71
72 /**47 /**
73 * Plugin author.48 * Plugin author
74 *49 *
75 * This is for user info only.50 * This is used on the plugin's "info" page, and on the application's "credits" page.
76 *51 * @var string The author's name
77 * @var string
78 */52 */
79 var $author = 'Dracones Incompertus';53 var $author = 'Dracones Incompertus';
80
81 /**54 /**
82 * Plugin author URL.55 * Plugin author URL
83 *56 *
84 * This is for user info only, not to be confused with help_url.57 * This is used on the plugin's "info" page, and on the application's "credits" page,
85 *58 * @var string The author's URL (optional)
86 * @var string
87 */59 */
88 var $author_url = '';60 var $author_url = '';
89
90 /**61 /**
91 * Globally unique code for this plugin functionality. 32 chars.62 * Unique code for this plugin functionality
92 *63 *
93 * A common code MIGHT be shared between different plugins providing the same functionnality.64 * THIS MUST BE SET BY YOUR PLUGIN!
94 * This allows to replace a given renderer with another one and keep the associations with posts.65 *
95 * Example: replacing a GIF smiley renderer with an SWF smiley renderer...66 * 32 characters max. Should be unique to each plugin, but a common code MIGHT be shared between
96 *67 * different plugins providing the same functionnality. This allows to replace a given renderer
97 * MUST BE SET BY THE PLUGIN!!!68 * with another one and keep the associations with posts. Example: replacing a GIF smiley renderer
98 *69 * with an SWF smiley renderer...
99 * @var string70 *
71 * For multiple instances of the same plugin, core will incrementally change this. Also,
72 * the user can change this via the plugin's settings page (Plugin variables (Advanced)).
73 * @var string A 32 character string identifying this plugin specific to this plugin
100 */74 */
101 var $code = '';75 var $code = '';
10276 /**
103 /**77 * Main group of the plugin
104 * Main group of the plugin.78 *
105 *79 * Accepts any value you want, but please pick from: "antispam, comments, pingers, renderers,
106 * Accepts any value you want, but please pick from the following:80 * toolbars, utilities, widgets, other". Eventually this will become a requirement so learn to
107 * "toolbars, widgets, renderers, antispam, pingers, tools, comments, other"81 * love it now :)
108 *82 * @var string 'antispam', 'comments', 'pingers', 'renderers', 'toolbars', 'utilities',
109 * @var string83 * 'widgets', 'other'
110 */84 */
111 var $group;85 var $group = 'other';
11286 /**
113 /**87 * URL for plugin support
114 * Sub-Group of the plugin.88 *
115 *89 * This is used on the Global settings => Plugins page and should point to a URL that offers
116 * OBSOLETE AND UN-USED! Left here only to not cause havoc with existing plugins90 * support and update info about the plugin. If empty no icon is displayed.
117 *91 * @var string A URL for support and update info about this plugin (optional)
118 * @var string
119 */
120 var $sub_group;
121
122 /**
123 * URL for more info about the plugin, author and new versions.
124 *
125 * This is for user info only. If empty, it defaults to 'something unknown right now',
126 *
127 * @var string
128 */92 */
129 var $help_url = '';93 var $help_url = '';
130
131 /**94 /**
132 * Number of allowed installs.95 * Number of allowed installs
133 *96 *
134 * When installing the plugin it gets checked if the plugin is already installed this97 * When the plugin is already installed this many times the option to install again is removed.
135 * many times. If so, the installation gets aborted.98 * Use 0 for unlimited, and any other number you see fit. Default is 1.
99 * @var integer How many times can this plugin be installed?
136 */100 */
137 var $number_of_installs;101 var $number_of_installs = 1;
138
139 /**102 /**
140 * Default priority.103 * Priority
141 *104 *
142 * Priority determines in which order the plugins get called.105 * Priority determines in which order the plugins get called. Range: 1 to 100 (the lower the
143 * Range: 1 to 100 (the lower the number, the earlier it gets called)106 * number, the earlier it gets called). Renderers use this to determine which renderer gets
144 *107 * called first. Also, adding plugins to the "Install widget" screen is by priority. Also,
145 * @var int108 * renderer checkboxes are by priority. Possibly other places as well.
109 *
110 * The installing user can change this in "Plugin variables (Advanced)"
111 * @var integer Rendering priority (lower number is first)
146 */112 */
147 var $priority = 50;113 var $priority = 50;
148
149 /**114 /**
150 * Plugin version number (max 42 chars, so obscure CVS Revision keywords get handled).115 * Plugin version number
151 *116 *
152 * This must be compatible to PHP's {@link version_compare()},117 * Max 42 chars, so obscure CVS Revision keywords get handled. This must be compatible to PHP's
153 * e.g. '1', '2', '1.1', '2.1b' and '10-1-1a' are fine.118 * {@link version_compare()}, e.g. '1', '2', '1.1', '2.1b' and '10-1-1a' are fine. This can be
154 *119 * used by other plugins when requiring your plugin through {@link Plugin::GetDependencies()}.
155 * This can be used by other plugins when requiring your plugin
156 * through {@link Plugin::GetDependencies()}.
157 *
158 * By increasing it you can request a call of {@link GetDbLayout()} upon instantiating.120 * By increasing it you can request a call of {@link GetDbLayout()} upon instantiating.
159 * If there are DB layout changes to be made, the plugin gets changed to status "needs_config".121 * If there are DB layout changes to be made, the plugin gets changed to status "needs_config".
160 *122 * @var string Incremental version number stored as a string
161 * @var string
162 */123 */
163 var $version = '0';124 var $version = '0';
164
165 /**125 /**
166 * Plugin name as it will appear in lists.126 * Plugin name
167 *127 *
168 * This should be no longer than 50 characters. To make it available for128 * Name as it will appear in lists, should be no longer than 50 characters so it fits nicely
169 * translations set it in function PluginInit() by using (for example)129 * on the (very crowded) Global settings => Plugins page. To make it available for translations
170 * $this->name = $this->T_('Plugin Name');130 * set it in function PluginInit() by using $this->name = $this->T_('A Great Plugin');
171 *131 * @var string Name of the plugin, used in lists
172 * @var string
173 */132 */
174 var $name = 'foo';133 var $name = 'foo';
175134 /**
176 /**135 * Plugin short description
177 * Plugin short description.136 *
178 *137 * This is limited to 255 characters but should be no longer than a line because it gets used
179 * This should be no longer than a line and is limited to 255 chars, but138 * on the (very crowded) Global settings => Plugins page. To make it available for translations
180 * "shorter is better"! To make it available for translations139 * set it in function PluginInit() by using $this->short_desc = $this->T_('Makes blogging easier');
181 * set it in function PluginInit() by using (for example)140 * @var string Short (one line) description of the plugin
182 * $this->short_desc = $this->T_('Makes blogging easier');141 */
183 *142 var $short_desc = 'No desc available';
184 * @var string143 /**
185 */144 * Plugin long description
186 var $short_desc;145 *
187146 * This can be as long and informative as you like, but remember you also should provide a
188 /**147 * readme.html file. To make it available for translations set it in function PluginInit()
189 * Plugin long description.148 * by using $this->long_desc = $this->T_('Makes blogging easier by making a toolbar that does stuff that gets rendered into stuff');
190 *149 *
191 * This should be no longer than a line or two. If much more is needed you150 * This is used on the plugin's "info" page, and on the application's "credits" page.
192 * should put it in your readme.html file instead. To make it available for151 * @var string Long description of the plugin, but not a replacement for a "readme" file
193 * translations set it in function PluginInit() by using (for example)152 */
194 * $this->long_desc = $this->T_('Makes blogging easier by making a toolbar that does stuff that gets rendered into stuff');153 var $long_desc = 'No long description available for this plugin';
195 *154 /**
196 * @var string155 * Name of the ping service
197 */156 * @var string Only if this is a ping plugin
198 var $long_desc;
199
200
201 /**
202 * Name of the ping service (if this is a ping plugin, see {@link Plugin::ItemSendPing()})
203 * @var string
204 */157 */
205 var $ping_service_name;158 var $ping_service_name;
206
207 /**159 /**
208 * Note about the ping service, used in the list of ping services in the blog settings160 * Note about the ping service
209 * (if this is a ping plugin, see {@link Plugin::ItemSendPing()})161 * @var string If this is a ping plugin, used in the list of ping services in the blog settings
210 * @var string
211 */162 */
212 var $ping_service_note;163 var $ping_service_note;
213
214 /**#@+
215 * Variables below MUST NOT be overriden or changed by you!
216 * @access private
217 */
218
219 /**164 /**
220 * Name of the current class. (AUTOMATIC)165 * Name of the current class
221 *166 *
222 * Will be set automatically (from filename) when registering plugin.167 * THIS MUST BE SET BY YOUR PLUGIN!
223 *168 *
224 * @var string169 * Will be set automatically (from file name) when registering plugin, but folder name and
170 * file name and the class declaration must match. "class thisismyplugin_plugin extends Plugin"
171 * appears in file name "_thisismyplugin.plugin.php" in folder name "thisismyplugin_plugin".
172 * @var string 40 characters max
225 */173 */
226 var $classname;174 var $classname;
227
228 /**175 /**
229 * Internal (DB) ID. (AUTOMATIC)176 * Internal (DB) ID
230 *177 *
231 * ID < 1 means 'NOT installed'178 * You do not set this but you can access it with $this->ID inside your plugin.
232 *179 * ID < 1 means 'NOT installed'.
233 * @var int180 * @var integer auto_incremented plugin ID
234 */181 */
235 var $ID = 0;182 var $ID = 0;
236
237 /**183 /**
238 * If the plugin provides settings, this will become the object to access them.184 * The object to access the (optional) plugin settings
239 *
240 * This gets instantianted on Plugin registration for PHP4 and through
241 * overloading in PHP5+, which means on first access.
242 *
243 * @see GetDefaultSettings()185 * @see GetDefaultSettings()
244 * @var PluginSettings186 * @var PluginSettings
245 */187 */
246 var $Settings;188 var $Settings;
247
248 /**189 /**
249 * If the plugin provides user settings, this will become the object to access them.190 * The object to access the (optional) user settings
250 *
251 * This gets instantianted on Plugin registration for PHP4 and through
252 * overloading in PHP5+, which means on first access.
253 *191 *
254 * NOTE: its methods use {@link $current_User::$ID} by default, but you may call it192 * NOTE: its methods use {@link $current_User::$ID} by default, but you may call it
255 * if there's no {@link $current_User} instantiated (yet).193 * if there is no {@link $current_User} instantiated (yet).
256 *
257 * @see GetDefaultUserSettings()194 * @see GetDefaultUserSettings()
258 * @var PluginUserSettings195 * @var PluginUserSettings
259 */196 */
260 var $UserSettings;197 var $UserSettings;
261
262 /**198 /**
263 * The status of the plugin.199 * The status of the plugin
264 *200 *
265 * Use {@link set_status()} to change it, if you need to.201 * Use {@link set_status()} to change it, if you need to. Either 'enabled', 'disabled',
266 * Either 'enabled', 'disabled', 'needs_config' or 'broken'.202 * 'needs_config' or 'broken', installation of the plugin will set it appropriately.
267 *203 * @var string 'enabled', 'disabled', 'needs_config', 'broken'
268 * @var string
269 */204 */
270 var $status;205 var $status;
271
272 /**206 /**
273 * The "mother" object, where this Plugin got instantiated from.207 * The "mother" object, where this Plugin got instantiated from
274 *208 * @deprecated since before time began (which is something of a miracle eh?)
275 * @deprecated since 2.0
276 * @var Plugins|Plugins_admin209 * @var Plugins|Plugins_admin
277 */210 */
278 var $Plugins;211 var $Plugins;
279
280 /**212 /**
281 * The translations keyed by locale. They get loaded through include() of _global.php.213 * The translations keyed by locale
282 * @see Plugin::T_()214 *
283 * @var array215 * They get loaded through include() of _global.php.
216 * @var array Array of string translations, English => Something else
284 */217 */
285 var $_trans = array();218 var $_trans = array();
286
287 /**219 /**
288 * Has the global po/php/_global.php file (where translation for220 * Has _global.php been loaded?
289 * all languages can be put into) been loaded?
290 *221 *
222 * Has the global po/_global.xx.php file (translation for language xx) been loaded?
291 * @var boolean223 * @var boolean
292 */224 */
293 var $_trans_loaded_global = false;225 var $_trans_loaded_global = false;
294226
295 /**#@-*/
296
297
298 /**227 /**
299 * Constructor.228 * Constructor
300 *229 *
301 * You should not use a constructor with your plugin, but the230 * You should not use a constructor with your plugin, but the
302 * {@link Plugin::PluginInit()} method instead!231 * {@link Plugin::PluginInit()} method instead!
@@ -307,152 +236,229 @@
307236
308237
309 /**238 /**
310 * Init the Plugin after it has been registered/instantiated.239 * Internal Event: Called after the plugin has been installed
311 *240 */
312 * Should set name, short description, and long description in a localizable fashion.241 function AfterInstall()
313 *242 {
314 * This gets called on every instantiated plugin, also if it's just for243 }
315 * discovering the list of available plugins in the backoffice.244
316 *245
317 * Use this to validate Settings/requirements and/or cache them into class properties.246 /**
318 *247 * Internal Event: Your plugin gets notified here just before it gets disabled
319 * @param array Associative array of parameters.248 *
320 * 'is_installed': true, if the plugin is installed; false if not (probably it got discovered then)249 * You cannot prevent this, but only clean up stuff if you have to.
321 * 'db_row': an array with the columns of the plugin DB entry (in T_plugins).250 */
322 * This is empty, if the plugin is not installed!251 function BeforeDisable()
323 * E.g., 'plug_version' might be interesting to compare again "$this->version".252 {
324 *253 }
325 * @return boolean If this method returns false, the Plugin gets unregistered (for the current request only).254
326 */255
327 function PluginInit( & $params )256 /**
328 {257 * Internal Event: Called when a plugin is not enabled
329 // NOTE: the code below is just to handle stuff that has been deprecated since258 *
330 // b2evolution 1.9. You don't have to include this, if you override this method.259 * Event handler: Called when a plugin is not enabled and the admin tries to enable the
331260 * plugin, changes its configuration/settings, and after installation. Use this if your
332 if( is_null($this->short_desc) )261 * plugin needs configuration before it can be used.
333 { // may have been set in plugin's constructor (which is deprecated since 1.9)262 * @return true|string True if the plugin can be enabled/activated, a string with an
334 $this->short_desc = T_('No desc available');263 * error/note otherwise.
335 }264 */
336 if( is_null($this->long_desc) )265 function BeforeEnable()
337 { // may have been set in plugin's constructor (which is deprecated since 1.9)266 {
338 $this->long_desc = T_('No long description available');267 return true;
339 }268 }
340269
341 return true;270
342 }271 /**
343272 * Internal Event: Called before the plugin is going to be installed
344273 *
345 // Plugin information (settings, DB layout, ..): {{{274 * This is the hook to create any DB tables or the like. If you just want
346275 * to add a note use {@link Plugin::msg()} (and return true).
347 /**276 * @return true|string True if the plugin can be enabled/activated, a string with an
348 * Define default settings here.277 * error/note otherwise.
349 * Those can then be edited in the backoffice.278 */
350 *279 function BeforeInstall()
351 * You can access them in the plugin through the member object280 {
352 * {@link Plugin::$Settings}, e.g.:281 return true;
353 * <code>$this->Settings->get( 'my_param' );</code>282 }
354 *283
355 * fp> this is unclear: You probably don't need to set or change values (other than the284
356 * defaultvalues), but if you know what you're doing, see285 /**
357 * {@link PluginSettings}, where {@link Plugin::$Settings} gets derived from.286 * Internal Event: Called before the plugin is going to be un-installed
358 *287 *
359 * NOTE: this method gets called by b2evo when instantiating the plugin288 * This is the hook to remove any files or the like - tables with canonical names (see
360 * settings and when the settings get displayed for editing in the backoffice.289 * {@link Plugin::get_sql_table()}), are handled internally. See {@link BeforeUninstallPayload()}
361 * In the second case, $params['for_editing'] will be true.290 * for the corresponding payload handler, which you can request to invoke by returning
362 *291 * NULL here. Note: this method gets called again, if the uninstallation has to be
363 * @todo 3.0 fp> 1) This is not an event: RENAME to lowercase (in b2evo 3.0)292 * confirmed, either because you've requested a call to {@link BeforeUninstallPayload()}
364 * dh> Not only events are CamelCase, but "interactions" with the Plugins(_admin) class, too!293 * or there are tables to be dropped (what the admin user has to confirm).
365 * Maybe it should get prefixed with "Plugin"?!294 *
366 * The intention is: all interfacing methods are camel-cased. That makes a lot of sense,295 * This should cleanup everything without confirmation!
367 * given the provided helpers (get_plugin_url etc).296 * @param array Associative array of parameters. 'unattended': true if Uninstall is
368 * This applies to the other todos below, too.297 * unattended (e.g., the /install action "deletedb" uses it).
369 * @todo 3.0 fp> 2) This defines more than Default values :: confusing name298 * @return boolean|NULL true when it's ok to uninstall, false on failure (the plugin won't
370 * @todo name tentative get_general_param_definitions()299 * get uninstalled then). You should add the reason for it through {@link Plugin::msg()}.
371 *300 * NULL requests to execute the {@link BeforeUninstallPayload()} method.
372 * @param array Associative array of parameters (since 1.9).301 */
373 * 'for_editing': true, if the settings get queried for editing;302 function BeforeUninstall( & $params )
374 * false, if they get queried for instantiating {@link Plugin::$Settings}.303 {
375 * @return array304 return true;
305 }
306
307
308 /**
309 * Internal Event: Invoked to display the payload before uninstalling the plugin
310 *
311 * You have to request a call to this during the plugin uninstall procedure by returning
312 * NULL in {@link BeforeUninstall()}. If your plugin uses canonical table names (see
313 * {@link Plugin::get_sql_table()}), there will be already a list of those tables
314 * included in it. Do not end the form, just add own inputs or hidden keys to it.
315 * @param array Associative array of parameters. 'Form': The {@link Form} that
316 * asks the user for confirmation (by reference).
317 */
318 function BeforeUninstallPayload( & $params )
319 {
320 }
321
322
323 /**
324 * Internal Event: Display a template
325 *
326 * Use {@link Plugin::GetProvidedTemplates()} to return a list of names that you register.
327 * @param array Associative array of parameters. 'template': name of template to be
328 * displayed (from the list of {@link Plugin::GetProvidedTemplates()}). If your Plugin
329 * registers only one template you can ignore it.
330 */
331 function DisplayTemplate( & $params )
332 {
333 }
334
335
336 /**
337 * Internal Event: Execute/handle a cron job
338 *
339 * Internal Event: Execute/handle a cron job, which has been scheduled by the admin out
340 * of the list that the Plugin provides (see {@link GetCronJobs()}).
341 * @param array Associative array of parameters
342 * - 'ctrl': The "ctrl" name as defined in {@link GetCronJobs()}
343 * - 'params': The "params" value as defined in {@link GetCronJobs()}, plus "ctsk_ID" which holds the cron task ID.
344 * @return array with keys "code" (integer, 1 is ok), "message" (gets logged)
345 */
346 function ExecCronJob( & $params )
347 {
348 }
349
350
351 /**
352 * Internal Event: Define default Plugin settings
353 *
354 * This defines settings that are available on the Global settings => Plugins => {{a plugin}}
355 * page. You can access them in the plugin through the member object {@link Plugin::$Settings},
356 * e.g.: <code>$this->Settings->get( 'my_param' );</code>
357 *
358 * NOTE: this method gets called by the application when instantiating the plugin settings
359 * and when the settings get displayed for editing in the backoffice. In the second case,
360 * $params['for_editing'] will be true.
361 *
376 * The array to be returned should define the names of the settings as keys (max length is 30 chars)362 * The array to be returned should define the names of the settings as keys (max length is 30 chars)
377 * and assign an array with the following keys to them (only 'label' is required):363 * and assign an array with the following keys to them (only 'label' is required):
378 *364
379 * 'label': Name/Title of the param, gets displayed as label for the input field, or365 * <ul>
380 * as "legend" tag with types "array" and "fieldset".366 * <li>'label': Name/Title of the param, gets displayed as label for the input field, or as
381 * 'defaultvalue': Default value for the setting, defaults to '' (empty string)367 * "legend" tag with types "array" and "fieldset".</li>
382 * 'type', which can be:368 * <li>'type', which can be:<ul>
383 * 'info': not an input - just a label followed by information (text, link, image - whatever)369 * <li>'info': not an input - just a label followed by information (text, link, image - whatever)</li>
384 * 'info': if type is info then use info to supply the actual information370 * <li>'text' (default): a simple string</li>
385 * 'text' (default): a simple string371 * <li>'password': like text, but hidden during input</li>
386 * 'password': like text, but hidden during input372 * <li>'html_input' : like text, but allows html</li>
387 * 'html_input' : like text, but allows html373 * <li>'checkbox': either 0 or 1</li>
388 * 'checkbox': either 0 or 1374 * <li>'integer': a number (no float, can have leading "+" or "-") (like 'text' for input,
389 * 'integer': a number (no float, can have leading "+" or "-") (like 'text' for input, but gets validated when submitting)375 * but gets validated when submitting)</li>
390 * 'float': a floating number (can have leading "+" or "-", e.g. "+1", "-0.05") (like 'text' for input, but gets validated when submitting)376 * <li>'float': a floating number (can have leading "+" or "-", e.g. "+1", "-0.05") (like
391 * 'textarea': several lines of input. The following can be set for this type:377 * 'text' for input, but gets validated when submitting)</li>
392 * 'rows': number of rows378 * <li>'textarea': several lines of input. The following can be set for this type:<ul>
393 * 'cols': number of columns379 * <li>'rows': number of rows</li>
394 * 'html_textarea': like textarea, but allows html380 * <li>'cols': number of columns</li>
395 * 'select': a drop down field; you must set 'options' for it:381 * </ul></li>
396 * 'options': an array of options ('value' => 'description'), see {@link Form::select_input_array()}.382 * <li>'html_textarea': like textarea, but allows html</li>
397 * 'select_blog': a drop down field, providing all existing blogs (Blog ID is the value or "" if "allow_none" is true) (WARNING: does not scale - not recommended)383 * <li>'select': a drop down field; you must set 'options' for it:<ul>
398 * 'select_group': a drop down field, providing all existing groups (Group ID is the value or "" if "allow_none" is true)384 * <li>'options': an array of options ('value' => 'description'), see {@link Form::select_input_array()}.</li>
399 * 'select_user': a drop down field, providing all existing groups (User ID is the value or "" if "allow_none" is true) (WARNING: does not scale - not recommended)385 * </ul></li>
400 * 'array': a subset of settings. The value gets automagically (un)serialized through get() and set().386 * <li>'select_blog': a drop down field, providing all existing blogs (Blog ID is the value or
401 * The following keys apply to this type:387 * "" if "allow_none" is true) (WARNING: does not scale - not recommended)</li>
402 * 'entries': an array with meta information about sub-settings388 * <li>'select_group': a drop down field, providing all existing groups (Group ID is the value
403 * (which can be everything from the top-level, except: "valid_pattern", "valid_range").389 * or "" if "allow_none" is true)</li>
404 * Note: currently there's no type forcing or checking390 * <li>'select_user': a drop down field, providing all existing groups (User ID is the value or
405 * for sub-entries involved (e.g., if you have an entry of type "integer", you could get391 * "" if "allow_none" is true) (WARNING: does not scale - not recommended)</li>
406 * a non-numeric string there).392 * </ul></li>
407 * fp> TODO: !!!! very unsafe393 * <li>'array': a subset of settings. The value gets automagically (un)serialized through get()
408 * 'key': defines the key to use for each entry. This may be a text input for example394 * and set(). The following keys apply to this type:<ul>
409 * (with label, note etc). (optional, default is numeric keys, which are not editable)395 * <li>'entries': an array with meta information about sub-settings (which can be everything from
410 * 'max_count': maximum count of sets (optional, default is no restriction)396 * the top-level, except: "valid_pattern", "valid_range"). Note: currently there's no type
411 * 'min_count': minimum count of sets (optional, default is no restriction)397 * forcing or checking for sub-entries involved (e.g., if you have an entry of type "integer",
412 * 'note' (gets displayed as a note to the param field),398 * you could get a non-numeric string there). fp> TODO: !!!! very unsafe</li>
413 * 'size': Size of the HTML input field (applies to types 'text', 'password' and 'integer'; defaults to 15)399 * <li>'key': defines the key to use for each entry. This may be a text input for example
414 * 'maxlength': maxlength attribute for the input field (See 'size' above; defaults to no limit)400 * (with label, note etc). (optional, default is numeric keys, which are not editable)</li>
415 * 'disabled': if true, it adds a 'disabled="disabled"' html attribute to the element and the value cannot be changed401 * <li>'max_count': maximum count of sets (optional, default is no restriction)</li>
416 * 'no_edit': if true, the setting is not editable. This is useful for internal settings.402 * <li>'min_count': minimum count of sets (optional, default is no restriction)</li>
417 * 'allow_none': set this to true to have "None" in the options list for types 'select_group' and 'select_user'.403 * </ul></li>
418 * 'valid_pattern': A regular expression pattern that the value must match.404 * <li>'size': Size of the HTML input field (applies to types 'text', 'password' and 'integer';
419 * This is either just a regexp pattern as string or an array405 * defaults to 15)</li>
420 * with the keys 'pattern' and 'error' to define a custom error message.406 * <li>'maxlength': maxlength attribute for the input field (See 'size' above; defaults to
421 * 'valid_range': An array with keys 'min', 'max' and (optionally) 'error' to define407 * no limit)</li>
422 * a custom error message. At least "min" or "max" must be given.408 * <li>'disabled': if true, it adds a 'disabled="disabled"' html attribute to the element and
423 * 'help': can be:409 * the value cannot be changed</li>
424 * '#anchor': anchor that gets appended to {@link $help_url}410 * <li>'no_edit': if true, the setting is not editable. This is useful for internal settings.</li>
425 * true: the settings name/key gets transformed to an html ID and gets used as anchor to {@link $help_url}.411 * <li>'allow_none': set this to true to have "None" in the options list for types 'select_group'
426 * 'http://example.com/uri': a full URL (starting with http:// or https://)412 * and 'select_user'.</li>
427 * 'layout': Use this to visually group your settings.413 * <li>'multiple': This allows to select multiple values in a SELECT (including select_*) (boolean)</li>
428 * Either 'begin_fieldset', 'end_fieldset' or 'separator'. You can use 'label' for 'begin_fieldset'.414 * <li>'valid_pattern': A regular expression pattern that the value must match. This is either
429 * 'multiple': This allows to select multiple values in a SELECT (including select_*) (boolean)415 * just a regexp pattern as string or an array with the keys 'pattern' and 'error' to define
430 * 'id', 'onchange', 'onclick', 'onfocus', 'onkeyup', 'onkeydown', 'onreset', 'onselect', 'cols', 'rows', 'maxlength':416 * a custom error message.</li>
431 * get passed through as attributes to the form/input element.417 * <li>'valid_range': An array with keys 'min', 'max' and (optionally) 'error' to define a
432 *418 * custom error message. At least "min" or "max" must be given.</li>
433 * e.g.:419 * <li>'help': can be:<ul>
420 * <li>'#anchor': anchor that gets appended to {@link $help_url}</li>
421 * <li>true: the settings name/key gets transformed to an html ID and gets used as anchor to {@link $help_url}.</li>
422 * <li>'http://example.com/uri': a full URL (starting with http:// or https://)</li>
423 * </ul></li>
424 * <li>'defaultvalue': Default value for the setting, defaults to '' (empty string)</li>
425 * <li>'note' (gets displayed as a note to the param field).</li>
426 * <li>'layout': Use this to visually group your settings. Either 'begin_fieldset', 'end_fieldset'
427 * or 'separator'. You can use 'label' for 'begin_fieldset'.</li>
428 * <li>'id', 'onchange', 'onclick', 'onfocus', 'onkeyup', 'onkeydown', 'onreset', 'onselect', 'cols', 'rows', 'maxlength':
429 * get passed through as attributes to the form/input element.</li>
430 * </ul>
431 *
432 * Example:
434 * <code>433 * <code>
435 * return array(434 * return array(
436 * 'my_param' => array(435 * 'my_param' => array(
437 * 'label' => $this->T_('My Param'),436 * 'label' => $this->T_('My Param'),
438 * 'defaultvalue' => '10',437 * 'defaultvalue' => '10',
438 * 'valid_pattern' => array( 'pattern' => '[1-9]\d+', $this->T_('The value must be >= 10.') ),
439 * 'note' => $this->T_('Quite cool, eh?'),439 * 'note' => $this->T_('Quite cool, eh?'),
440 * 'valid_pattern' => array( 'pattern' => '[1-9]\d+', $this->T_('The value must be >= 10.') ),
441 * ),440 * ),
442 * 'another_param' => array( // this one has no 'note'441 * 'another_param' => array( // this one has no 'note'
443 * 'label' => $this->T_('My checkbox'),442 * 'label' => $this->T_('My checkbox'),
443 * 'type' => 'checkbox',
444 * 'defaultvalue' => '1',444 * 'defaultvalue' => '1',
445 * 'type' => 'checkbox',
446 * ),445 * ),
447 * array( 'layout' => 'separator' ),446 * array( 'layout' => 'separator' ),
448 * 'my_select' => array(447 * 'my_select' => array(
449 * 'label' => $this->T_('Selector'),448 * 'label' => $this->T_('Selector'),
449 * 'type' => 'select',
450 * 'options' => array(
451 * 'sun' => $this->T_('Sunday')
452 * 'mon' => $this->T_('Monday')
453 * ),
450 * 'defaultvalue' => 'one',454 * 'defaultvalue' => 'one',
451 * 'type' => 'select',455 * )
452 * 'options' => array( 'sun' => $this->T_('Sunday'), 'mon' => $this->T_('Monday') ),456 * );
453 * ) );
454 * </code>457 * </code>
455 *458 * @param array Associative array of parameters
459 * - 'for_editing': 'true' if the settings get queried for editing, 'false' if they get
460 * queried for instantiating {@link Plugin::$Settings}.
461 * @return array Array of plugin's settings
456 */462 */
457 function GetDefaultSettings( & $params )463 function GetDefaultSettings( & $params )
458 {464 {
@@ -461,23 +467,34 @@
461467
462468
463 /**469 /**
464 * Define here default user settings that are then available in the backoffice.470 * Internal Event: Define default Blog settings
471 * @see Plugin::GetDefaultSettings()
472 * @param array Associative array of parameters. 'for_editing': true if the settings get
473 * queried for editing, false if they get queried for instantiating {@link Plugin::$UserSettings}.
474 * @return array See {@link Plugin::GetDefaultSettings()}.
475 */
476 function GetDefaultBlogSettings( & $params )
477 {
478 return array();
479 }
480
481
482 /**
483 * Internal Event: Define default User settings
465 *484 *
466 * You can access them in the plugin through the member object485 * This method behaves exactly like {@link Plugin::GetDefaultSettings()}, except that it
467 * {@link $UserSettings}, e.g.:486 * defines user specific settings instead of global settings. You can access them in the
487 * plugin through the member object {@link $UserSettings} e.g.:
468 * <code>$this->UserSettings->get( 'my_param' );</code>488 * <code>$this->UserSettings->get( 'my_param' );</code>
469 *489 *
470 * This method behaves exactly like {@link Plugin::GetDefaultSettings()},490 * This hook accepts special cases for a user's avatar and (brief) biography. These fields
471 * except that it defines user specific settings instead of global settings.491 * are stored in the core table, but it is up to your plugin to use them. To activate them
472 *492 * in a user's profile add either of these to your user settings array:
473 * @todo 3.0 fp> 1) This is not an event: RENAME to lowercase (in b2evo 3.0)493 * <code>'use_avatar' => true,</code>
474 * @todo 3.0 fp> 2) This defines more than Default values :: confusing name494 * <code>'use_biography' => true,</code>
475 * @todo name tentative get_user_param_definitions()
476 *
477 * @see Plugin::GetDefaultSettings()495 * @see Plugin::GetDefaultSettings()
478 * @param array Associative array of parameters.496 * @param array Associative array of parameters. 'for_editing': true if the settings get
479 * 'for_editing': true, if the settings get queried for editing;497 * queried for editing, false if they get queried for instantiating {@link Plugin::$UserSettings}.
480 * false, if they get queried for instantiating {@link Plugin::$UserSettings}.
481 * @return array See {@link Plugin::GetDefaultSettings()}.498 * @return array See {@link Plugin::GetDefaultSettings()}.
482 */499 */
483 function GetDefaultUserSettings( & $params )500 function GetDefaultUserSettings( & $params )
@@ -487,23 +504,7 @@
487504
488505
489 /**506 /**
490 * Define here default collection/blog settings that are to be made available in the backoffice.507 * Internal Event: Define default Widget settings
491 *
492 * @see Plugin::GetDefaultSettings()
493 * @param array Associative array of parameters.
494 * 'for_editing': true, if the settings get queried for editing;
495 * false, if they get queried for instantiating {@link Plugin::$UserSettings}.
496 * @return array See {@link Plugin::GetDefaultSettings()}.
497 */
498 function GetDefaultBlogSettings( & $params )
499 {
500 return array();
501 }
502
503
504 /**
505 * Get definitions for widget specific editable params
506 *
507 * @see Plugin::GetDefaultSettings()508 * @see Plugin::GetDefaultSettings()
508 * @param local params like 'for_editing' => true509 * @param local params like 'for_editing' => true
509 */510 */
@@ -514,71 +515,20 @@
514515
515516
516 /**517 /**
517 * Get the list of dependencies that the plugin has.
518 *
519 * This gets checked on install or uninstall of a plugin.
520 *
521 * There are two <b>classes</b> of dependencies:
522 * - 'recommends': This is just a recommendation. If it cannot get fulfilled
523 * there will just be a note added on install.
524 * - 'requires': A plugin cannot be installed if the dependencies cannot get
525 * fulfilled. Also, a plugin cannot get uninstalled, if another
526 * plugin depends on it.
527 *
528 * Each <b>class</b> of dependency can have the following types:
529 * - 'events_by_one': A list of eventlists that have to be provided by a single plugin,
530 * e.g., <code>array( array('CaptchaPayload', 'CaptchaValidated') )</code>
531 * to look for a plugin that provides both events.
532 * - 'plugins':
533 * A list of plugins, either just the plugin's classname or an array with
534 * classname and minimum version of the plugin (see {@link Plugin::$version}).
535 * E.g.: <code>array( 'test_plugin', '1' )</code> to require at least version "1"
536 * of the test plugin.
537 * - 'app_min': Minimum application (QP) version, e.g. "1.0".
538 * This way you can make sure that the hooks you need are implemented in the core.
539 *
540 * @see test_plugin::GetDependencies()
541 * @return array
542 */
543 function GetDependencies()
544 {
545 return array(); // no dependencies by default, of course
546 }
547
548
549 /**
550 * This method should return your DB schema, consisting of a list of CREATE TABLE
551 * queries.
552 *
553 * The DB gets changed accordingly on installing or enabling your Plugin.
554 *
555 * If you want to change your DB layout in a new version of your Plugin, simply
556 * adjust the queries here and increase {@link Plugin::$version}, because this will
557 * request to check the current DB layout against the one you require.
558 *
559 * For restrictions see {@link db_delta()}.
560 */
561 function GetDbLayout()
562 {
563 return array();
564 }
565
566
567 /**
568 * This method gets asked when plugins get installed and allows you to return a list
569 * of extra events, which your plugin triggers itself (e.g. through
570 * {@link $Plugins->trigger_event()}).
571 *
572 * NOTE: PLEASE use a distinct prefix for the event name, e.g. "$this->classname".
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches