wp/wp-content/plugins/page-columnist/page-columnist.php
changeset 14 00ac8f60d73f
parent 13 d255fe9cd479
child 15 3d4e9c994f10
equal deleted inserted replaced
13:d255fe9cd479 14:00ac8f60d73f
     1 <?php
       
     2 /***************************************************************************************************************************************************
       
     3 Plugin Name:  Page Columnist
       
     4 Plugin URI: http://www.code-styling.de/english/development/wordpress-plugin-page-columnist-en
       
     5 Description:  A simple way to get single posts and static pages content arranged in column layout, supports also overview page behavior.
       
     6 Author: Heiko Rabe
       
     7 Author URI: http://www.code-styling.de/
       
     8 Version: 1.7.3
       
     9 ***************************************************************************************************************************************************
       
    10  License:
       
    11  =======
       
    12  Copyright 2009 Heiko Rabe  (email : info@code-styling.de)
       
    13 
       
    14  This program is free software; you can redistribute it and/or modify
       
    15  it under the terms of the GNU General Public License as published by
       
    16  the Free Software Foundation; either version 2 of the License, or
       
    17  (at your option) any later version.
       
    18  
       
    19  This program is distributed in the hope that it will be useful,
       
    20  but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    22  GNU General Public License for more details.
       
    23 
       
    24  You should have received a copy of the GNU General Public License
       
    25  along with this program; if not, write to the Free Software
       
    26  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    27 ****************************************************************************************************************************************************/
       
    28 
       
    29 //avoid direct calls to this file, because now WP core and framework has been used
       
    30 if (!function_exists ('add_action')) {
       
    31 		header('Status: 403 Forbidden');
       
    32 		header('HTTP/1.1 403 Forbidden');
       
    33 		exit();
       
    34 }
       
    35 
       
    36 //WordPress definitions
       
    37 if ( !defined('WP_CONTENT_URL') )
       
    38 	define('WP_CONTENT_URL', get_option('siteurl') . '/wp-content');
       
    39 if ( !defined('WP_CONTENT_DIR') )
       
    40 	define('WP_CONTENT_DIR', ABSPATH . 'wp-content');
       
    41 if ( !defined('WP_PLUGIN_URL') ) 
       
    42 	define('WP_PLUGIN_URL', WP_CONTENT_URL.'/plugins');
       
    43 if ( !defined('WP_PLUGIN_DIR') ) 
       
    44 	define('WP_PLUGIN_DIR', WP_CONTENT_DIR.'/plugins');
       
    45 if ( !defined('PLUGINDIR') )
       
    46 	define( 'PLUGINDIR', 'wp-content/plugins' ); // Relative to ABSPATH.  For back compat.
       
    47 	
       
    48 if ( !defined('WP_LANG_DIR') )
       
    49 	define('WP_LANG_DIR', WP_CONTENT_DIR . '/languages');
       
    50 
       
    51 //safety patch for changed activation procedure in WP 3.0
       
    52 //without this test it won't be activatable at less than 3.0	
       
    53 if (!function_exists('cspc_on_activate_plugin'))	{
       
    54 
       
    55 function cspc_on_activate_plugin() {
       
    56 	global $page_columnist_plug, $wpdb;
       
    57 	//self deactivation in error cases
       
    58 	if (is_object($page_columnist_plug)) {
       
    59 		$version_error = $page_columnist_plug->_get_version_errors();
       
    60 		if (is_array($version_error) && count($version_error) != 0) {
       
    61 			$row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'active_plugins' ) );
       
    62 			if ( is_object( $row ) ) {
       
    63 				$current = maybe_unserialize( $row->option_value );
       
    64 				if (array_search($page_columnist_plug->basename, $current) !== false) {		
       
    65 					array_splice($current, array_search($page_columnist_plug->basename, $current), 1 );
       
    66 					update_option('active_plugins', $current);
       
    67 				}
       
    68 			}
       
    69 			exit();
       
    70 		}
       
    71 	}
       
    72 	if (!get_option('cspc_page_columnist'))
       
    73 		update_option('cspc_page_columnist', get_option('cspc_page_columnist', $page_columnist_plug->defaults));
       
    74 }		
       
    75 function cspc_on_deactivate_plugin() {
       
    76 	//currently empty
       
    77 }
       
    78 register_activation_hook(plugin_basename(__FILE__), 'cspc_on_activate_plugin');	
       
    79 register_deactivation_hook(plugin_basename(__FILE__), 'cspc_on_deactivate_plugin');
       
    80 
       
    81 	
       
    82 class Page_columnist_page_transition {
       
    83 
       
    84 	function Page_columnist_page_transition(&$plugin, $page_id = false) {
       
    85 		$this->plugin 		= $plugin; //reference to owner plugin
       
    86 		$this->transition 	= $this->plugin->page_default_trans;
       
    87 		$this->data			= array();
       
    88 		$this->data_keys	= array('spacing', 'columns', 'overflow', 'multiposts');
       
    89 		$this->padding		= '<span style="font-style:italic;color:#f00">'.__('* content missing', $this->plugin->textdomain).'</span>';
       
    90 		if ($page_id) $this->load($page_id);
       
    91 		else $this->page_id = 0;
       
    92 	}
       
    93 
       
    94 	function load($page_id) {
       
    95 		$this->page_id		= ($page_id ? $page_id : 0);		
       
    96 		$this->transition 	= $this->plugin->page_default_trans;
       
    97 		$this->data			= array();
       
    98 		$res = explode('|', get_post_meta($this->page_id, '_cspc-page-transitions', true));	
       
    99 		$num = count($res);
       
   100 		if ($num > 0) {
       
   101 			if (in_array($res[0], array_keys($this->plugin->page_transitions))) {
       
   102 				$this->transition = $res[0];
       
   103 				if ($num > 1) {
       
   104 					$this->data = unserialize($res[1]);
       
   105 				}
       
   106 			}
       
   107 		}
       
   108 	}
       
   109 	
       
   110 	function save() {
       
   111 		if ($this->page_id > 0) {
       
   112 			$value = $this->transition.'|'.serialize($this->data);
       
   113 			update_post_meta($this->page_id, '_cspc-page-transitions', $value);
       
   114 		}
       
   115 	}
       
   116 	
       
   117 	function update_and_save() {
       
   118 		if (isset($_POST['cspc-page-transition']) && in_array($_POST['cspc-page-transition'], array_keys($this->plugin->page_transitions))) {
       
   119 			$this->transition = $_POST['cspc-page-transition'];
       
   120 		}
       
   121 		if (isset($_POST['cspc-count-columns'])) {
       
   122 			$this->data['columns'] = (int)$_POST['cspc-count-columns'];
       
   123 		}
       
   124 		if (isset($_POST['cspc-overflow-paging'])) {
       
   125 			$this->data['overflow'] = $_POST['cspc-overflow-paging'];
       
   126 			if($this->data['overflow'] != 'hidden' && $this->data['overflow'] != 'virtual') {
       
   127 				$this->data['overflow'] = 'hidden';
       
   128 			}
       
   129 		}	
       
   130 		if (isset($_POST['cspc-multiposts-paging']) && in_array($_POST['cspc-multiposts-paging'], $this->plugin->multiposts_style)) {
       
   131 			$this->data['multiposts'] = $_POST['cspc-multiposts-paging'];
       
   132 		}
       
   133 		if (!isset($this->data['distribution']) || !is_array($this->data['distribution'])) $this->data['distribution'] = array();
       
   134 		$this->save();
       
   135 	}
       
   136 	
       
   137 	
       
   138 	function spacing() {
       
   139 		return (isset($this->data['spacing']) ? (float)$this->data['spacing'] : (float)$this->plugin->options->spacing);
       
   140 	}
       
   141 	
       
   142 	function columns() {
       
   143 		return (isset($this->data['columns']) ? (int)$this->data['columns'] : 2);
       
   144 	}
       
   145 	
       
   146 	function overflow() {
       
   147 		return (isset($this->data['overflow']) ? $this->data['overflow'] : 'hidden');
       
   148 	}
       
   149 	
       
   150 	function multiposts() {
       
   151 		return (isset($this->data['multiposts']) ? $this->data['multiposts'] : 'same');
       
   152 	}
       
   153 	
       
   154 	function execute(&$pages) {
       
   155 		return call_user_func(array(&$this, '_exec_'.str_replace('-','_',$this->transition)), $pages);
       
   156 	}
       
   157 
       
   158 	function _padding_pages($needed, &$pages) {
       
   159 		$res = array();
       
   160 		while(count($pages) % $needed != 0) $pages[] = $this->padding; //padding count of sub pages
       
   161 		if ($this->overflow() == 'hidden') {
       
   162 			$res[] = array_slice($pages, 0, $needed);
       
   163 		}else{
       
   164 			$res = array_chunk($pages, $needed);
       
   165 		}
       
   166 		return $res;
       
   167 	}
       
   168 
       
   169 	function _get_distribution($num, $remaining) {
       
   170 		$res = array();
       
   171 		if (!is_array($this->data['distribution']) || !isset($this->data['distribution'][$num])) {
       
   172 			$perc = $remaining / $num;
       
   173 			for ($i=0; $i<$num; $i++) $res[] = $perc;
       
   174 		}
       
   175 		else{
       
   176 			$sum = 0.0;
       
   177 			for ($i=0; $i<$num; $i++) $sum += (float)$this->data['distribution'][$num][$i];
       
   178 			for ($i=0; $i<$num; $i++) {
       
   179 				$res[]= ($remaining * ((float)$this->data['distribution'][$num][$i] / $sum));
       
   180 			}
       
   181 		}
       
   182 		return $res;
       
   183 	}
       
   184 	
       
   185 	function _columnize_pages($num, $pages) {
       
   186 		$res = '';
       
   187 		$base = 100.0;
       
   188 		$spacing = $this->spacing();
       
   189 		$remaining = ($base - ($num - 1) * $spacing);
       
   190 		$dist = $this->_get_distribution($num, $remaining);
       
   191 		$lorr = 'left';
       
   192 		global $wp_locale;
       
   193 		if ($wp_locale->text_direction == 'rtl') {
       
   194 			$lorr = 'right'; //make it work at RTL languages
       
   195 		}
       
   196 		for ($i=0; $i<$num; $i++) {
       
   197 			$page = $pages[$i];
       
   198 			$perc = $dist[$i];
       
   199 			if ($this->plugin->is_MSIE()) {
       
   200 				//IE is not able to calculate column sizes well, several 100% sums leads to get the last column display wrapped under the first
       
   201 				//in several cases (mostly where a periodic fraction of 1/3 or 1/6 occures) , IE seems to reach by internal rounding errors more than 100% of available width
       
   202 				$margin_left_i = ($i==0 ? 0 : $spacing * 0.66);
       
   203 			}
       
   204 			else{
       
   205 				$margin_left_i = ($i==0 ? 0 : $spacing);
       
   206 			}
       
   207 			$extend = $this->plugin->is_page_preview() ? ' data="'.$perc.'"' : '';
       
   208 			$res .= "<div id=\"cspc-column-$i\" class=\"cspc-column\" style=\"display:inline-block;float:$lorr;margin-$lorr:$margin_left_i%;width:$perc%;overflow:hidden;\"$extend>";
       
   209 			if (has_filter('the_content', 'wpautop') && !preg_match('/^\s*<div/', $page)) $res .= '<p>';
       
   210 			$res .= $page;
       
   211 			if (has_filter('the_content', 'wpautop') && !preg_match('/<\/p>\s*$/', $page)) $res .= '</p>';
       
   212 			$res .= '</div>';
       
   213 		}
       
   214 		return $res;		
       
   215 	}
       
   216 	
       
   217 	function _columnize_fullsize($page, $clearleft = false) {
       
   218 		if (empty($page)) return '';
       
   219 		$res = ($clearleft ? '<div id="cspc-footer" style="clear:left;">' : '<div id="cspc-header">');
       
   220 		if (has_filter('the_content', 'wpautop') && !preg_match('/^\s*<div/', $page)) $res .= '<p>';
       
   221 		$res .= $page;
       
   222 		if (has_filter('the_content', 'wpautop') &&!preg_match('/<\/p>\s*$/', $page)) $res .= '</p>';
       
   223 		$res .= '</div>';
       
   224 		if ($clearleft) $res .='<div style="clear:both; height:0;"> </div>';
       
   225 		return $res;
       
   226 	}
       
   227 	
       
   228 	function _exec_cspc_trans_wordpress(&$pages) {
       
   229 		return $pages;
       
   230 	}
       
   231 
       
   232 	function _exec_cspc_trans_ordinary(&$pages) {
       
   233 		$res = "<div id=\"$this->transition-wrap\" class=\"cspc-wrapper\">";
       
   234 		$res .= "\n\n";
       
   235 		$res .= implode("\n\n", $pages);
       
   236 		$res .='</div>';
       
   237 		return array($res);
       
   238 	}
       
   239 	
       
   240 	function _exec_cspc_trans_columns(&$pages) {
       
   241 		$work = $this->_padding_pages($this->columns(), $pages);	
       
   242 		$out = array();
       
   243 		for ($i=0; $i<count($work); $i++) {
       
   244 			$num = count($work[$i]);
       
   245 			$res = "<div id=\"$this->transition-wrap\" class=\"cspc-wrapper\">";
       
   246 			$res .= '<div id="cspc-content" style="clear:left;">';
       
   247 			$res .= $this->_columnize_pages($num, $work[$i]);
       
   248 			$res .= '<div style="clear:left;"></div></div>';
       
   249 			$res .= '</div>';
       
   250 			$out[] = $res;
       
   251 		}
       
   252 		return $out;
       
   253 	}
       
   254 	
       
   255 	function _exec_cspc_trans_header(&$pages) {
       
   256 		$work = $this->_padding_pages($this->columns() + 1, $pages);	
       
   257 		$out = array();
       
   258 		for ($i=0; $i<count($work); $i++) {
       
   259 			$top = array_shift($work[$i]);
       
   260 			$num = count($work[$i]);
       
   261 			$res = "<div id=\"$this->transition-wrap\" class=\"cspc-wrapper\">";
       
   262 			$res .= $this->_columnize_fullsize($top);
       
   263 			$res .= '<div id="cspc-content" style="clear:left;">';
       
   264 			$res .= $this->_columnize_pages($num, $work[$i]);
       
   265 			$res .= '<div style="clear:left;"></div></div>';
       
   266 			$res .= '</div>';
       
   267 			$out[] = $res;
       
   268 		}
       
   269 		return $out;
       
   270 	}
       
   271 	
       
   272 	function _exec_cspc_trans_footer(&$pages) {
       
   273 		$work = $this->_padding_pages($this->columns() + 1, $pages);	
       
   274 		$out = array();
       
   275 		for ($i=0; $i<count($work); $i++) {
       
   276 			$last = end($work[$i]);
       
   277 			$num = count($work[$i]) -1;
       
   278 			$work[$i] = ($num > 0 ? array_slice($work[$i],0,$num) : array());
       
   279 			$res = "<div id=\"$this->transition-wrap\" class=\"cspc-wrapper\">";
       
   280 			$res .= '<div id="cspc-content" style="clear:left;">';
       
   281 			$res .= $this->_columnize_pages($num, $work[$i]);
       
   282 			$res .= '<div style="clear:left;"></div></div>';
       
   283 			$res .= $this->_columnize_fullsize($last, true);
       
   284 			$res .= '</div>';
       
   285 			$out[] = $res;
       
   286 		}
       
   287 		return $out;
       
   288 	}
       
   289 	
       
   290 	function _exec_cspc_trans_interior(&$pages) {
       
   291 		$work = $this->_padding_pages($this->columns() + 2, $pages);	
       
   292 		$out = array();
       
   293 		for ($i=0; $i<count($work); $i++) {
       
   294 			$top = array_shift($work[$i]);
       
   295 			$num = count($work[$i]) -1;
       
   296 			$last = ($num > 0 ? end($work[$i]) : '');
       
   297 			$work[$i] = ($num > 0 ? array_slice($work[$i],0,$num) : array());
       
   298 			$res = "<div id=\"$this->transition-wrap\" class=\"cspc-wrapper\">";
       
   299 			$res .= $this->_columnize_fullsize($top);
       
   300 			$res .= '<div id="cspc-content" style="clear:left;">';
       
   301 			$res .= $this->_columnize_pages($num, $work[$i]);
       
   302 			$res .= '<div style="clear:left;"></div></div>';
       
   303 			$res .= $this->_columnize_fullsize($last, true);
       
   304 			$res .= '</div>';
       
   305 			$out[] = $res;
       
   306 		}
       
   307 		return $out;
       
   308 	}
       
   309 }
       
   310 
       
   311 
       
   312 //page_columnist Plugin class	
       
   313 class Plugin_page_columnist {
       
   314 	
       
   315 	//initializes the whole plugin and enables the activation/deactivation handling
       
   316 	function Plugin_page_columnist() {
       
   317 		global $wp_version;
       
   318 
       
   319 		$this->l10n_ready 							= false;
       
   320 		
       
   321 		//own plugin data
       
   322 		$this->basename 							= plugin_basename(__FILE__);
       
   323 		$this->url									= WP_PLUGIN_URL.'/'.dirname($this->basename);
       
   324 		$this->textdomain 							= basename($this->basename);
       
   325 		$this->textdomain							= substr($this->textdomain, 0, strrpos($this->textdomain, '.'));
       
   326 		$this->versions								= new stdClass;
       
   327 		$this->versions->required					= array( 'php' => '4.4.2', 'wp' => '2.7');
       
   328 		$this->versions->found						= array( 'php' => phpversion(), 'wp' => $wp_version);
       
   329 		$this->versions->above_27					= !version_compare($this->versions->found['wp'], '2.8alpha', '<');
       
   330 		$this->do_resample_page						= false;
       
   331 		$this->multiposts_style						= array('flat', 'same', 'wp');
       
   332 
       
   333 		$this->page_default_trans 					= 'cspc-trans-wordpress';
       
   334 		
       
   335 		$this->defaults								= new stdClass;
       
   336 		$this->defaults->spacing					= 3.0;
       
   337 		$this->defaults->preview_assistent			= false;
       
   338 		
       
   339 		$this->options								= get_option('cspc_page_columnist', $this->defaults);
       
   340 		$stored = get_object_vars($this->options);
       
   341 		$defaults = get_object_vars($this->defaults);
       
   342 		foreach($defaults as $key => $value) {
       
   343 			if (!isset($stored[$key])) $this->options->$key = $value;
       
   344 		}
       
   345 									
       
   346 		add_action('init', 							array(&$this, 'on_init'));
       
   347 		add_action('admin_init',					array(&$this, 'on_admin_init'));
       
   348 		add_action('wp_head',						array(&$this, 'on_wp_head'));
       
   349 		add_action('wp_footer',						array(&$this, 'on_wp_footer'));
       
   350 		add_action('admin_head', 					array(&$this, 'on_admin_head'));
       
   351 		add_action('edit_page_form',				array(&$this, 'on_extend_html_editor'));
       
   352 		add_action('edit_form_advanced',			array(&$this, 'on_extend_html_editor'));
       
   353 		add_action('manage_pages_custom_column',	array(&$this, 'on_manage_custom_column'), 10, 2);
       
   354 		add_action('manage_posts_custom_column',	array(&$this, 'on_manage_custom_column'), 10, 2);
       
   355 		add_action('wp_insert_post', 				array(&$this, 'on_wp_insert_post'), 10, 2);
       
   356 		add_action('loop_start', 					array(&$this, 'on_loop_start'), 0 );
       
   357 		add_action('the_post', 						array(&$this, 'on_the_post'), 0 );
       
   358 		add_action('template_redirect',				array(&$this, 'on_template_redirect'));
       
   359 		add_filter('mce_buttons',					array(&$this, 'on_filter_mce_buttons'));
       
   360 
       
   361 		$this->_display_version_errors();
       
   362 		
       
   363 		//TODO:  future development should be able to deal with removing the ugly wpautop algorithm
       
   364 		//remove_filter('the_content', 'wpautop');
       
   365 	}
       
   366 
       
   367 	function _get_version_errors() {
       
   368 		$res = array();
       
   369 		foreach($this->versions->required as $key => $value) {
       
   370 			if (!version_compare($this->versions->found[$key], $value, '>=')) {
       
   371 				$res[strtoupper($key).' Version'] = array('required' => $value, 'found' =>  $this->versions->found[$key]);
       
   372 			}
       
   373 		}
       
   374 		return $res;
       
   375 	}
       
   376 	
       
   377 	function _display_version_errors() {
       
   378 		if (isset($_GET['action']) && isset($_GET['plugin']) && ($_GET['action'] == 'error_scrape') && ($_GET['plugin'] == $this->basename )) {
       
   379 			$this->setup_translation();
       
   380 			$version_error = $this->_get_version_errors();
       
   381 			if (count($version_error) != 0) {
       
   382 				echo "<table>";
       
   383 				echo "<tr style=\"font-size: 12px;\"><td><strong style=\"border-bottom: 1px solid #000;\">".__('Plugin can not be activated.', $this->textdomain)."</strong></td><td> | ".__('required', $this->textdomain)."</td><td> | ".__('actual', $this->textdomain)."</td></tr>";			
       
   384 				foreach($version_error as $key => $value) {
       
   385 					echo "<tr style=\"font-size: 12px;\"><td>$key</td><td align=\"center\"> &gt;= <strong>".$value['required']."</strong></td><td align=\"center\"><span style=\"color:#f00;\">".$value['found']."</span></td></tr>";
       
   386 				}
       
   387 				echo "</table>";
       
   388 			}
       
   389 		}
       
   390 	}	
       
   391 	
       
   392 	//load and setup the necessary translation files
       
   393 	function setup_translation() {
       
   394 		if (!$this->l10n_ready) {
       
   395 			$abs_rel_path = str_replace(ABSPATH, '', WP_PLUGIN_DIR.'/'.dirname($this->basename));
       
   396 			$plugin_rel_path = dirname($this->basename);		
       
   397 			load_plugin_textdomain($this->textdomain, $abs_rel_path, $plugin_rel_path);
       
   398 			$this->l10n_ready = true;
       
   399 		}
       
   400 	}
       
   401 	
       
   402 	//is the browser of current user IE ?
       
   403 	function is_MSIE() {
       
   404 		return preg_match('/msie/i', $_SERVER['HTTP_USER_AGENT']) && !preg_match('/opera/i', $_SERVER['HTTP_USER_AGENT']);
       
   405 	}
       
   406 	
       
   407 	//do we show a frontend page in preview mode ?
       
   408 	function is_page_preview() {
       
   409 		$id = (isset($_GET['preview_id']) ? (int)$_GET['preview_id'] : 0);
       
   410 		if ($id == 0 && isset($_GET['post_id'])) $id = (int)$_GET['post_id'];
       
   411 		if ($id == 0 && isset($_GET['page_id'])) $id = (int)$_GET['page_id'];
       
   412 		if ($id == 0 && isset($_GET['p'])) $id = (int)$_GET['p'];
       
   413 		$preview = (isset($_GET['preview']) ? $_GET['preview'] : '');
       
   414 		if ($id > 0 && $preview == 'true' && $this->options->preview_assistent) {
       
   415 			global $wpdb;
       
   416 			$type = $wpdb->get_results("SELECT post_type FROM $wpdb->posts WHERE ID=$id");
       
   417 			if (count($type) && ($type[0]->post_type == 'page' || $type[0]->post_type == 'post')){
       
   418 				switch($type[0]->post_type) {
       
   419 					case 'post':
       
   420 						return current_user_can('edit_post', $id);
       
   421 						break;
       
   422 					case 'page':
       
   423 						return current_user_can('edit_page', $id);
       
   424 						break;
       
   425 					default:
       
   426 						return false;
       
   427 						break;
       
   428 				}
       
   429 			}
       
   430 		}
       
   431 		return false;
       
   432 	}
       
   433 
       
   434 	//detects if we a currently render the posts or pages edit overview table page
       
   435 	function is_page_overview() {
       
   436 		global $pagenow;
       
   437 		return (is_admin() && ($pagenow == 'edit-pages.php' || $pagenow == 'edit.php'));
       
   438 	}
       
   439 
       
   440 	//detects if we a currently render the posts or pages editor page
       
   441 	function is_page_editor() {
       
   442 		global $pagenow;
       
   443 		return (is_admin() && (
       
   444 			($pagenow == 'page.php') || ($pagenow == 'page-new.php')
       
   445 			||
       
   446 			($pagenow == 'post.php') || ($pagenow == 'post-new.php')
       
   447 			)
       
   448 		);
       
   449 	}
       
   450 	
       
   451 	//gets called by WordPress action "init" after WordPress core is up and running
       
   452 	function on_init() {		
       
   453 		//ensures the correct matching translation file gets loaded
       
   454 		$this->setup_translation();				
       
   455 		
       
   456 		$this->page_transitions = array(
       
   457 			'cspc-trans-wordpress' 		=> array('img-pos' =>   0, 'text' => __('WordPress - Next Page (default)', $this->textdomain), 'default' => true),
       
   458 			'cspc-trans-ordinary'		=> array('img-pos' => -16, 'text' => __('Ordinary Plain Page', $this->textdomain)),
       
   459 			'cspc-trans-columns'		=> array('img-pos' => -32, 'text' => __('Every Sub Page as Column', $this->textdomain)),
       
   460 			'cspc-trans-header'			=> array('img-pos' => -48, 'text' => __('First Sub Page as Header', $this->textdomain)),
       
   461 			'cspc-trans-footer'			=> array('img-pos' => -64, 'text' => __('Last Sub Page as Footer', $this->textdomain)),
       
   462 			'cspc-trans-interior'		=> array('img-pos' => -80, 'text' => __('Interior as Columns', $this->textdomain)),
       
   463 		);
       
   464 				
       
   465 		if ($this->is_page_preview() && !defined('DOING_AJAX')) {
       
   466 			wp_enqueue_script('jquery-spin', $this->url.'/jquery.spin.js', array('jquery'));
       
   467 			wp_enqueue_script('cspc_page_columnist_assistance', $this->url.'/page-columnist-assistance.js', array('jquery', 'jquery-ui-draggable', 'jquery-spin'));
       
   468 			wp_enqueue_style('cspc_page_columnist_assistance', $this->url.'/page-columnist-assistance.css');
       
   469 		}		
       
   470 
       
   471 		if(defined('DOING_AJAX')) {
       
   472 			add_action('wp_ajax_cspc_save_changes', array(&$this, 'on_ajax_save_changes'));
       
   473 		}
       
   474 	}
       
   475 	
       
   476 	//gets called by WordPress action "admin_init" to be able to setup correctly in backend mode
       
   477 	function on_admin_init() {
       
   478 
       
   479 		if ($this->is_page_overview()) {
       
   480 			add_filter('manage_edit-pages_columns', array(&$this,'on_filter_manage_columns'));
       
   481 			add_filter('manage_posts_columns', array(&$this,'on_filter_manage_columns'));
       
   482 		}
       
   483 		
       
   484 		if ($this->is_page_editor()) {
       
   485 			add_meta_box('cspc-page-transitions', __('Page Columnist', $this->textdomain) , array(&$this, 'on_print_metabox_content_cspc_page_transitions'), 'page', 'side', 'core');
       
   486 			add_meta_box('cspc-page-transitions', __('Page Columnist', $this->textdomain) , array(&$this, 'on_print_metabox_content_cspc_page_transitions'), 'post', 'side', 'core');
       
   487 			wp_enqueue_script('jquery-spin', $this->url.'/jquery.spin.js', array('jquery'));		
       
   488 		}		
       
   489 	}
       
   490 	
       
   491 	//gets called by action "wp_head" to configure the preview assistance
       
   492 	function on_wp_head() {
       
   493 		if ($this->is_page_preview()) {
       
   494 			$id = (isset($_GET['preview_id']) ? (int)$_GET['preview_id'] : 0);
       
   495 			if ($id == 0 && isset($_GET['post_id'])) $id = (int)$_GET['post_id'];
       
   496 			if ($id == 0 && isset($_GET['page_id'])) $id = (int)$_GET['page_id'];
       
   497 			if ($id == 0 && isset($_GET['p'])) $id = (int)$_GET['p'];
       
   498 			$pt = new Page_columnist_page_transition($this, $id);			
       
   499 		?>
       
   500 		<script type="text/javascript">
       
   501 		var cspc_page_columnist_l10n = {
       
   502 			adminUrl: '<?php echo admin_url(); ?>',
       
   503 			pageId: <?php echo $id; ?>,
       
   504 			imageBasePath: '<?php echo $this->url.'/img/'; ?>'
       
   505 		};
       
   506 		</script>
       
   507 		<?php }
       
   508 	}
       
   509 	
       
   510 	//gets called by WordPress action "wp_footer" to print in preview mode the assistance
       
   511 	function on_wp_footer() {
       
   512 		if ($this->is_page_preview()) { 
       
   513 			$id = (isset($_GET['preview_id']) ? (int)$_GET['preview_id'] : 0);
       
   514 			if ($id == 0 && isset($_GET['post_id'])) $id = (int)$_GET['post_id'];
       
   515 			if ($id == 0 && isset($_GET['page_id'])) $id = (int)$_GET['page_id'];
       
   516 			if ($id == 0 && isset($_GET['p'])) $id = (int)$_GET['p'];
       
   517 			$pt = new Page_columnist_page_transition($this, $id);
       
   518 		?>
       
   519 		<div id="cspc-assist-bar">
       
   520 			<div id="cspc-assist-bar-content"> 
       
   521 				<div class="cspc-section">
       
   522 					<strong style="font-size: 18px;"><i><a href="http://www.code-styling.de" target="_blank">CodeStyling Project &copy 2009</a></i></strong>
       
   523 				</div>
       
   524 				<div class="cspc-section">
       
   525 					<input autocomplete="off" id="cspc-columns-sizing" name="cspc-columns-sizing" type="checkbox"><label for="cspc-columns-sizing"><?php _e('enable column resizing', $this->textdomain); ?></label>
       
   526 				</div>
       
   527 				<div class="cspc-section">
       
   528 					<input autocomplete="off" id="cspc-col-spacing" type="text" value="<?php echo (float)$pt->spacing(); ?>" readonly="readonly" style="width:20px;background-color:#fff;color:#000;"/>
       
   529 					<label>&nbsp;&nbsp;<?php _e('% spacing', $this->textdomain); ?></label>
       
   530 					&nbsp;
       
   531 					<input autocomplete="off" id="cspc-default-spacing" name="cspc-default-spacing" type="checkbox"><label for="cspc-default-spacing"><?php _e('default spacing', $this->textdomain); ?></label></input>
       
   532 					&nbsp;
       
   533 					<a id="cspc-save-changes" class="cspc-button" href="javascript:void(0);"><?php _e('save changes', $this->textdomain); ?></a>
       
   534 				</div>
       
   535 				<div style="clear:left;"> </div>
       
   536 			</div>
       
   537 			<div id="cspc-assist-bar-expander"><?php _e('Page Columnist &bull; Assistance', $this->textdomain); ?></div>
       
   538 		</div>
       
   539 		<?php }
       
   540 	}
       
   541 		
       
   542 	//gets called by WordPress action "admin_head"
       
   543 	function on_admin_head() {
       
   544 		if ($this->is_page_overview() || $this->is_page_editor()) :	?>
       
   545 			<style type="text/css">
       
   546 				.cspc-page-table td { font-size: 11px; vertical-align: middle; }
       
   547 				#cspc-page-definition td { font-size: 11px; vertical-align: middle; }
       
   548 				#cspc-page-transition-col { width: 56px; } 
       
   549 				.cspc-page-transition-row { width: 30px; height: 16px; padding-left:16px; }
       
   550 				.cspc-page-transition-box { padding: 0px 3px 3px 18px; line-height: 18px; white-space: nowrap; }
       
   551 				*:first-child + html #cspc-page-transitions input { margin-top: -3px; margin-left: 0xp;} /* IE fix */
       
   552 				*:first-child + html #cspc-page-transitions p { margin: 3px; }
       
   553 				#cspc-default-column-spacing { font-size:12px;width:26px;background-color:#fff;color:#000;height:19px; padding: 1px 0px 2px 1px; line-height:15px;} /* border: solid 1px #000; line-height:15px;}*/
       
   554 				*:first-child + html #cspc-default-column-spacing, html:first-child>b\ody #cspc-default-column-spacing  { height: 15px; } /* IE and Opera */
       
   555 				<?php foreach($this->page_transitions as $key => $val) : ?>
       
   556 				.<?php echo $key; ?> { background: transparent url(<?php echo $this->url.'/states.png'; ?>) no-repeat left <?php echo $val['img-pos']; ?>px; }
       
   557 				<?php endforeach; ?>
       
   558 			</style>
       
   559 			<?php if ($this->is_page_editor()) : ?>
       
   560 				<script type="text/javascript">
       
   561 					jQuery(document).ready(function(){
       
   562 						jQuery('#cspc-default-column-spacing').spin({max:10,min:0,imageBasePath: '<?php echo $this->url.'/img/'; ?>', interval: 0.5 });
       
   563 					});
       
   564 				</script>
       
   565 			<?php endif; ?>
       
   566 		<?php endif;
       
   567 	}
       
   568 
       
   569 	//insert the nextpage button to TinyMCE button bar if it's not already there
       
   570 	function on_filter_mce_buttons($buttons) {
       
   571 		if ($this->is_page_editor()) {
       
   572 			if (!in_array('wp_page', $buttons)) {
       
   573 				if (!in_array('wp_more', $buttons)) {
       
   574 					$last = array_pop($buttons);
       
   575 					$buttons[] = "wp_page";
       
   576 					$buttons[] = $last;
       
   577 				}else{
       
   578 					$txt = implode('|', $buttons);
       
   579 					$txt = str_replace('wp_more|','wp_more|wp_page|', $txt);
       
   580 					$buttons = explode('|', $txt);
       
   581 				}
       
   582 			}
       
   583 		}
       
   584 		return $buttons;		
       
   585 	}
       
   586 
       
   587 	//insert nextpage button to HTML editor, if not already present there
       
   588 	function on_extend_html_editor() {
       
   589 		if ($this->is_page_editor()) : ?>
       
   590 		<script type="text/javascript">
       
   591 			//<![CDATA[
       
   592 			jQuery(document).ready(function() {
       
   593 				if (!jQuery("#ed_next").length) {
       
   594 					content = '<input id="ed_next" class="ed_button" type="button" value="<?php _e('nextpage',$this->textdomain); ?>" title="<?php _e('insert Page break', $this->textdomain); ?>" onclick="edInsertContent(edCanvas, \'<!--nextpage-->\');" accesskey="t" />';
       
   595 					jQuery("#ed_toolbar").append(content);
       
   596 				}
       
   597 			});
       
   598 			//]]>
       
   599 		</script>
       
   600 		<?php endif;
       
   601 	}
       
   602 	
       
   603 	//append a custom column at edit posts/pages overview
       
   604 	function on_filter_manage_columns($columns) {
       
   605 		$columns['cspc-page-transition-col'] = __('Cols', $this->textdomain);
       
   606 		return $columns;
       
   607 	}
       
   608 	
       
   609 	//add content to the new edit posts / pages overview column
       
   610 	function on_manage_custom_column($column_name, $id) {
       
   611 		if ($column_name == 'cspc-page-transition-col') {
       
   612 			$pt = new Page_columnist_page_transition($this, $id);
       
   613 			if ($pt->transition != 'cspc-trans-wordpress' && $pt->transition != 'cspc-trans-ordinary') {
       
   614 				echo "<div class=\"cspc-page-transition-row $pt->transition\">&nbsp; (".$pt->columns().")</div>";
       
   615 			}
       
   616 			else{
       
   617 				echo "<div class=\"cspc-page-transition-row $pt->transition\">&nbsp; (-)</div>";
       
   618 			}
       
   619 		}
       
   620 	}
       
   621 	
       
   622 	//save the page transition mode setting of page/post, if something has been saved
       
   623 	function on_wp_insert_post($post_ID, $post) {	
       
   624 		$my_id 		= ((isset($_POST['wp-preview']) && $_POST['wp-preview'] == 'dopreview') ? $_POST['post_ID'] : $post_ID);	
       
   625 		$my_type 	= ((isset($_POST['wp-preview']) && $_POST['wp-preview'] == 'dopreview') ? $_POST['post_type'] : $post->post_type);
       
   626 
       
   627 		switch($my_type) {
       
   628 			case 'post':
       
   629 				if(!current_user_can('edit_post', $my_id)) return;
       
   630 				break;
       
   631 			case 'page':
       
   632 				if (!current_user_can('edit_page', $my_id)) return;
       
   633 				break;
       
   634 			default:
       
   635 				return;
       
   636 				break;
       
   637 		}
       
   638 		
       
   639 		if (($my_type == 'page') || ($my_type == 'post')) { 
       
   640 		
       
   641 			$pt = new Page_columnist_page_transition($this, $my_id);
       
   642 			$pt->update_and_save();
       
   643 						
       
   644 			$this->options->preview_assistent = (isset($_POST['cspc-preview-assistent']) ? (bool)$_POST['cspc-preview-assistent'] : $this->defaults->preview_assistent);
       
   645 			$this->options->spacing = (isset($_POST['cspc-default-column-spacing']) ? (float)$_POST['cspc-default-column-spacing'] : $this->defaults->spacing);
       
   646 			update_option('cspc_page_columnist', $this->options);
       
   647 		}
       
   648 	}
       
   649 	
       
   650 	//save the changes the user made at preview assistent 
       
   651 	function on_ajax_save_changes() {	
       
   652 		$page_id = (int)$_POST['page_id'];
       
   653 		$spacing = (float)$_POST['spacing'];
       
   654 		$default_spacing = ($_POST['default_spacing'] == 'true' ? true : false);
       
   655 
       
   656 		global $wpdb;
       
   657 		$type = $wpdb->get_results("SELECT post_type FROM $wpdb->posts WHERE ID=$page_id");
       
   658 		if (count($type) && ($type[0]->post_type == 'page' || $type[0]->post_type == 'post')){
       
   659 			$checked = false;
       
   660 			switch($type[0]->post_type) {
       
   661 				case 'post':
       
   662 					$checked = current_user_can('edit_post', $page_id);
       
   663 					break;
       
   664 				case 'page':
       
   665 					$checked = current_user_can('edit_page', $page_id);
       
   666 					break;
       
   667 				default:
       
   668 					$checked = false;
       
   669 					break;
       
   670 			}
       
   671 			if ($checked) {
       
   672 				$pt = new Page_columnist_page_transition($this, $page_id);
       
   673 				$pt->data['spacing'] = $spacing;
       
   674 				if (!is_array($pt->data['distribution'])) $pt->data['distribution'] = array();
       
   675 				$pt->data['distribution'][$pt->columns()] = explode('|',$_POST['distribution']);
       
   676 				$pt->save();				
       
   677 				if ($default_spacing) {
       
   678 					$this->options->spacing = $spacing;
       
   679 					update_option('cspc_page_columnist', $this->options);
       
   680 				}
       
   681 				exit();
       
   682 			}
       
   683 		}
       
   684 		header('Status: 404 Not Found');
       
   685 		header('HTTP/1.1 404 Not Found');
       
   686 		_e('You do not have the permission to edit this page.', $this->textdomain);
       
   687 		exit();
       
   688 	}
       
   689 	
       
   690 	
       
   691 	//ouput the content of new one sidebar box at page/post editing
       
   692 	function on_print_metabox_content_cspc_page_transitions($data) {
       
   693 		$pt = new Page_columnist_page_transition($this, $data->ID); ?>
       
   694 		<div style="margin-bottom:5px; border-bottom: dotted 1px #999; padding: 5px 0px;vertical-align:top;">
       
   695 			<table class="cspc-page-table">
       
   696 				<tr>
       
   697 				 <td><input id="cspc-default-column-spacing" name="cspc-default-column-spacing" type="text" value="<?php echo $this->options->spacing; ?>" readonly="readonly" autocomplete="off"/></td>
       
   698 				 <td>&nbsp;<label for="cspc-default-column-spacing"><?php _e('% column default spacing', $this->textdomain); ?></label><td>
       
   699 				</tr>
       
   700 			</table>
       
   701 		</div>
       
   702 		<div>
       
   703 			<table class="cspc-page-table">
       
   704 			<?php
       
   705 			foreach($this->page_transitions as $type => $val) : ?>
       
   706 				<tr><td>
       
   707 					<input id="<?php echo $type; ?>" type="radio" name="cspc-page-transition" value="<?php echo $type; ?>" <?php if($type == $pt->transition) echo 'checked="checked"'; ?>/>
       
   708 				</td>
       
   709 				<td>
       
   710 					<label for="<?php echo $type; ?>" class="cspc-page-transition-box <?php echo $type; ?>"><?php echo $val['text']; ?></label>
       
   711 				</td></tr>
       
   712 			<?php endforeach; ?>
       
   713 			</table>
       
   714 		</div>
       
   715 		<table id="cspc-page-definition" style="margin-top:5px; border-top: dotted 1px #999; padding: 5px 0px;table-layout:fixed;" width="100%" cellspacing="5px">
       
   716 			<tr>
       
   717 				<td width="30%"><?php _e('spacing:', $this->textdomain); ?></td><td width="70%"><strong><?php echo $pt->spacing(); ?> %</strong></td>
       
   718 			</tr>
       
   719 			<tr>
       
   720 				<td><?php _e('columns:', $this->textdomain); ?></td>
       
   721 				<td>
       
   722 					<?php for($i=2;$i<7; $i++) { ?>
       
   723 					<input id="cspc-count-columns-<?php echo $i; ?>" name="cspc-count-columns" type="radio" value="<?php echo $i; ?>" autocomplete="off" <?php if ($pt->columns() == $i) echo 'checked="checked" '; ?>><?php echo $i; ?></input>
       
   724 					<?php } ?>
       
   725 				</td>
       
   726 			</tr>
       
   727 			<tr>
       
   728 				<td style="vertical-align:top;"><?php _e('overflow:', $this->textdomain); ?></td>
       
   729 				<td>
       
   730 					<input id="cspc-overflow-hidden" name="cspc-overflow-paging" type="radio" value="hidden" <?php if ($pt->overflow() == 'hidden') echo 'checked="checked"'; ?> autocomplete="off"><?php _e('hide too much columns', $this->textdomain); ?></input><br/>
       
   731 					<input id="cspc-overflow-virtual" name="cspc-overflow-paging" type="radio" value="virtual" <?php if ($pt->overflow() == 'virtual') echo 'checked="checked"'; ?> autocomplete="off"/><?php _e('generate virtual pages', $this->textdomain); ?></input>
       
   732 				<td>
       
   733 			</tr>
       
   734 			<?php if ($this->versions->above_27) : ?>
       
   735 			<tr>
       
   736 				<td style="vertical-align:top;"><?php _e('at overview pages:', $this->textdomain); ?></td>
       
   737 				<td>
       
   738 					<input id="cspc-multiposts-same" name="cspc-multiposts-paging" type="radio" value="same" <?php if ($pt->multiposts() == 'same') echo 'checked="checked"'; ?> autocomplete="off"><?php _e('same as single pages', $this->textdomain); ?></input><br/>
       
   739 					<input id="cspc-multiposts-wp" name="cspc-multiposts-paging" type="radio" value="wp" <?php if ($pt->multiposts() == 'wp') echo 'checked="checked"'; ?> autocomplete="off"/><?php _e('pagination', $this->textdomain); ?></input><br/>
       
   740 					<input id="cspc-multiposts-flat" name="cspc-multiposts-paging" type="radio" value="flat" <?php if ($pt->multiposts() == 'flat') echo 'checked="checked"'; ?> autocomplete="off"/><?php _e('render flat single content', $this->textdomain); ?></input>
       
   741 				<td>
       
   742 			</tr>
       
   743 			<?php endif; ?>
       
   744 		</table>
       
   745 		<div style="margin-top:5px; border-top: dotted 1px #999; padding: 5px 0px;">
       
   746 			<table class="cspc-page-table">
       
   747 				<tr>
       
   748 					<td><input id="cspc-preview-assistent" name="cspc-preview-assistent" type="checkbox" <?php if($this->options->preview_assistent) echo 'checked="checked"'; ?>/></td>
       
   749 					<td><label for="cspc-preview-assistent">&nbsp;<?php _e('enable Assistance at Preview', $this->textdomain); ?></label></td>			
       
   750 				</tr>
       
   751 			</table>
       
   752 		</div>
       
   753 		<?php		
       
   754 	}
       
   755 	
       
   756 	//restructure the current page to meet the user configured column layout
       
   757 	function resample_page_content() {
       
   758 		global $post, $id, $page, $pages, $multipage, $numpages;
       
   759 	
       
   760 		$pt = new Page_columnist_page_transition($this, $post->ID);
       
   761 		//user can change overview pages to support also columnization, default is off
       
   762 		if (!is_single()) {
       
   763 			switch($pt->multiposts()) {
       
   764 				case 'wp': 
       
   765 					$pt->transition = $this->page_default_trans;
       
   766 					break;
       
   767 				case 'flat':
       
   768 					$pt->transition = 'cspc-trans-ordinary';
       
   769 					break;
       
   770 			}
       
   771 		}
       
   772 		if($pt->transition == $this->page_default_trans) return;
       
   773 		$pages = $pt->execute($pages);
       
   774 					
       
   775 		if (count($pages) > 1) {
       
   776 			$multipage = 1;
       
   777 			$numpages = count($pages);				
       
   778 		}
       
   779 		else{
       
   780 			$multipage = 0;
       
   781 			$numpages = 1;
       
   782 		}
       
   783 
       
   784 /*			
       
   785 		//TODO: future versions should check ugly invalid <p> based at shortcode api if possible
       
   786 		if (has_filter('the_content', 'wpautop')) {
       
   787 			preg_match('/'.get_shortcode_regex().'(\s\s|)/', $pages[0],$hits);
       
   788 			var_dump($hits);
       
   789 		}
       
   790 */		
       
   791 	}
       
   792 	
       
   793 	//beginning WP 2.8 the order of how hooks been called have been change
       
   794 	//that's why the handling of resampling the page if different for 2.7 and 2.8, this have to be respected
       
   795 	function on_the_post() {
       
   796 		if ($this->versions->above_27) {
       
   797 			$this->resample_page_content();
       
   798 		}
       
   799 	}
       
   800 	
       
   801 	//beginning WP 2.8 the order of how hooks been called have been change
       
   802 	//that's why the handling of resampling the page if different for 2.7 and 2.8, this have to be respected
       
   803 	function on_loop_start() {
       
   804 		if ($this->versions->above_27 == false) {
       
   805 			if (is_page() || is_single()) {
       
   806 				$this->resample_page_content();
       
   807 			}
       
   808 		}
       
   809 	}
       
   810 	
       
   811 	//if we are in none standard page mode, ensure a redirect to main page slug, if sub-page has been requested directly and doesn't support virtual paging
       
   812 	function on_template_redirect(){
       
   813 		global $post, $page;
       
   814 		if ($post->post_type == 'page' || $post->post_type == 'post') {
       
   815 			$pt = new Page_columnist_page_transition($this, $post->ID);
       
   816 			if (($pt->transition != $this->page_default_trans) && $page && $pt->overflow() == 'hidden') {
       
   817 				wp_redirect(get_permalink($post->ID));
       
   818 				exit();
       
   819 			}
       
   820 		}
       
   821 	}
       
   822 	
       
   823 }
       
   824 
       
   825 //nothing more remains to do as to create an instance of the plugin itself :-)
       
   826 global $page_columnist_plug; 
       
   827 $page_columnist_plug = new Plugin_page_columnist();
       
   828 
       
   829 }// if !function_exists('cspc_on_activate_plugin'))	{
       
   830 ?>