dom_array as $key => $node){ if( !is_array($node) || !array_key_exists('tag',$node) ){ continue; } $tag = $node['tag']; if( $tag != 'img' || !isset($node['attributes']['src']) ){ continue; } $resized_data = self::ResizedImage($node['attributes']); if( $resized_data !== false ){ $img = $resized_data['img']; $index = $resized_data['index']; $resized_src = \gp\tool::GetDir('/include/image.php',true).'?i='.$index.'&w='.$resized_data['w'].'&h='.$resized_data['h'].'&img='.rawurlencode($img); $gp_html_output->dom_array[$key]['attributes']['src'] = $resized_src; $img_list[$index][] = $resized_data['w'].'x'.$resized_data['h']; $img_list[$index] = array_unique($img_list[$index]); \gp_resized::$index[$index] = $img; } } $gp_html_output->Rebuild(); $html_content = $gp_html_output->result; self::ResizedImageUse($orig_list,$img_list); \gp_resized::SaveIndex(); } /** * Attempt to create a resized image * */ public static function ResizedImage($attributes){ global $dataDir, $dirPrefix; //height and width from style $css_w = null; $css_h = null; if( !empty($attributes['style']) ){ $css_args = explode(';',$attributes['style']); foreach($css_args as $css_arg){ $css_arg = explode(':',$css_arg); if( count($css_arg) != 2 ){ continue; } $css_key = strtolower(trim($css_arg[0])); $css_value = strtolower(trim($css_arg[1])); $px_pos = strpos($css_value,'px'); if( !$px_pos ){ continue; } if( $css_key == 'width' ){ $css_w = substr($css_value,0,$px_pos); }elseif( $css_key == 'height' ){ $css_h = substr($css_value,0,$px_pos); } } } //width attribute if( !$css_w && isset($attributes['width']) && is_numeric($attributes['width']) ){ $css_w = $attributes['width']; } //height attribute if( !$css_h && isset($attributes['height']) && is_numeric($attributes['height']) ){ $css_h = $attributes['height']; } if( !$css_w || !$css_h ){ return false; } //check src if( empty($attributes['src']) ){ return false; } $src = urldecode($attributes['src']); $img_dir = $dirPrefix.'/data/_uploaded'; if( $src[0] != '/' && strpos($src,$img_dir) !== 0 ){ return false; } $src_relative = substr($src,strlen($img_dir)); return self::CreateImage($src_relative,$css_w,$css_h); } /** * Create a resized image of the file at $src_relative * */ public static function CreateImage($src_relative, $width, $height){ global $dataDir; $src_path = $dataDir . '/data/_uploaded' . $src_relative; if( !file_exists($src_path) ){ return false; } //compare to actual size $src_img = \gp\tool\Image::getSrcImg($src_path); if( $src_img === false ){ return false; } //Original Size $actual_w = imagesx($src_img); $actual_h = imagesy($src_img); if( $actual_w <= $width && $actual_h <= $height ){ return false; } $info = \gp_resized::ImageInfo($src_relative, $width, $height); if( !$info ){ return false; } $dest_index = $info['index']; if( !$dest_index ){ $dest_index = \gp_resized::NewIndex(); } $dest_path = $dataDir . '/data/_resized/' . $dest_index . '/' . $info['name']; $exists_before = file_exists($dest_path); //make sure the folder exists if( !\gp\tool\Files::CheckDir( \gp\tool::DirName($dest_path) ) ){ return false; } //create new resized image if( !\gp\tool\Image::createImg($src_img, $dest_path, 0, 0, 0, 0, $width, $height, $actual_w, $actual_h, false, false, $src_path) ){ return false; } //not needed if the resized image is larger than the original if( filesize($dest_path) > filesize($src_path) ){ if( !$exists_before ){ unlink($dest_path); } return false; } $data = array(); $data['index'] = $dest_index; $data['w'] = $width; $data['h'] = $height; $data['img'] = $src_relative; return $data; } /** * Record where reduced images are being used so that we can delete them later if they are no longer referenced * ... no guarantee the reduced image won't be copy & pasted into other pages.. page copies would need to track the data as well * */ public static function ResizedImageUse($list_before,$list_after){ global $dataDir; //subtract uses no longer $subtract_use = self::UseDiff($list_before, $list_after); //add uses $add_use = self::UseDiff($list_after, $list_before); //save info for each image $all_imgs = array_keys($subtract_use + $add_use); foreach($all_imgs as $index){ $edited = false; $usage = \gp_resized::GetUsage($index); //add uses if( isset($add_use[$index]) && count($add_use[$index]) ){ $edited = true; foreach($add_use[$index] as $size){ if( isset($usage[$size]) ){ $usage[$size]['uses']++; }else{ $usage[$size]['uses'] = 1; $usage[$size]['created'] = time(); } $usage[$size]['touched'] = time(); } } //remove uses if( isset($subtract_use[$index]) && is_array($subtract_use[$index]) ){ $edited = true; foreach($subtract_use[$index] as $size){ if( isset($usage[$size]) ){ $usage[$size]['uses']--; }else{ $usage[$size]['uses'] = 0; $usage[$size]['created'] = time();//shouldn't happen } $usage[$size]['uses'] = max($usage[$size]['uses'],0); if( $usage[$size]['uses'] == 0 ){ self::DeleteUnused($index, $size); } $usage[$size]['touched'] = time(); } } //order usage by sizes: small to large uksort($usage,array('\\gp\\tool\\Editing', 'SizeCompare')); if( $edited ){ \gp_resized::SaveUsage($index,$usage); } } } /** * Delete unused images * if uses < 1, delete the file, but not the record * */ private static function DeleteUnused($index, $size){ global $dataDir; list($width,$height) = explode('x',$size); //make sure the image still exists if( !isset(\gp_resized::$index[$index]) ){ return; } $img = \gp_resized::$index[$index]; $info = \gp_resized::ImageInfo($img,$width,$height); if( !$info ){ return; } $full_path = $dataDir.'/data/_resized/'.$index.'/'.$info['name']; if( file_exists($full_path) ){ @unlink($full_path); } } /** * Get the use difference * */ private static function UseDiff( $a, $b){ $diff = $a; foreach($a as $index => $sizes){ if( isset($b[$index]) ){ $diff[$index] = array_diff($a[$index],$b[$index]); } } return $diff; } /** * Replace resized images with their originals * */ public static function RestoreImages($html_content,$img_list){ global $dirPrefix; includeFile('image.php'); \gp_resized::SetIndex(); // $images = array(); foreach($img_list as $index => $sizes){ if( !isset(\gp_resized::$index[$index]) ){ continue; } $img = \gp_resized::$index[$index]; $original_path = $dirPrefix.'/data/_uploaded'.$img; foreach($sizes as $size){ list($width,$height) = explode('x',$size); $resized_path = \gp\tool::GetDir('/include/image.php',true).'?i='.$index.'&w='.$width.'&h='.$height; //not searching for the whole path in case the image was renamed $images[$resized_path] = $original_path; } } //resize images $gp_html_output = new \gp\tool\Editing\HTML($html_content); foreach($gp_html_output->dom_array as $key => $node){ if( !is_array($node) || !array_key_exists('tag',$node) ){ continue; } $tag = $node['tag']; if( $tag != 'img' || !isset($node['attributes']['src']) ){ continue; } $src = $node['attributes']['src']; foreach($images as $resized => $original){ if( strpos($src,$resized) === 0 ){ $gp_html_output->dom_array[$key]['attributes']['src'] = $original; } } } $gp_html_output->Rebuild(); return $gp_html_output->result; } /** * Comare the sizes of two images * */ public static function SizeCompare($size1, $size2){ list($w1,$h1) = explode('x',$size1); list($w2,$h2) = explode('x',$size2); return ($w1*$h1) > ($w2*$h2); } /** * Clean a string that may be used as an internal file path * * @param string $path The string to be cleansed * @return string The cleansed string */ public static function CleanArg($path){ $path = self::Sanitize($path); //all forward slashes $path = str_replace('\\','/',$path); //remove directory style changes $path = str_replace(array('../','./','..'),array('','',''),$path); //change other characters to underscore $pattern = '#\\||\\:|\\?|\\*|"|<|>|[[:cntrl:]]#u'; $path = preg_replace( $pattern, '_', $path ) ; //reduce multiple slashes to single $pattern = '#\/+#'; $path = preg_replace( $pattern, '/', $path ) ; return $path; } /** * Clean a string for use as a page title (url) * Removes potentially problematic characters * * @param string $title The string to be cleansed * @param string $spaces The string spaces will be replaced with * @return string The cleansed string */ public static function CleanTitle($title,$spaces = '_'){ $title = self::Sanitize($title); if( empty($title) ){ return ''; } $title = str_replace(array('"',"'",'?','*',':'),array(''),$title); // # needed for entities $title = str_replace(array('<','>','|','\\'),array(' ',' ',' ','/'),$title); $title = preg_replace('#\.+([\\\\/])#','$1',$title); $title = trim($title,'/'); $title = trim($title); if( $spaces ){ $title = preg_replace( '#[[:space:]]#', $spaces, $title ); } return $title; } /** * Remove null and control characters from the string * @return string */ public static function Sanitize($string){ $string = \gp\tool\Files::NoNull($string); // Remove control characters [\x00-\x1F\x7F] $clean = ''; preg_match_all( '#[^[:cntrl:]]+#u', $string, $matches); foreach($matches[0] as $match){ $clean .= $match; } $clean = rawurldecode($clean); // remove percent encoded strings like %2e%2e%2f //recursively sanitize if( strlen($clean) !== strlen($string) ){ $clean = self::Sanitize($clean); } return $clean; } /** * Use HTML Tidy to validate the $text * Only runs when $config['HTML_Tidy'] is off * * @param string $text The html content to be checked. Passed by reference */ public static function tidyFix(&$text,$ignore_config = false){ global $config; if( !$ignore_config ){ if( empty($config['HTML_Tidy']) || $config['HTML_Tidy'] == 'off' ){ return true; } } if( !function_exists('tidy_parse_string') ){ return false; } $options = array(); $options['wrap'] = 0; //keeps tidy from wrapping... want the least amount of space changing as possible.. could get rid of spaces between words with the str_replaces below $options['doctype'] = 'omit'; //omit, auto, strict, transitional, user $options['drop-empty-paras'] = true; //drop empty paragraphs $options['output-xhtml'] = true; //need this so that
will be
.. etc $options['show-body-only'] = true; $options['hide-comments'] = false; $tidy = tidy_parse_string($text,$options,'utf8'); tidy_clean_repair($tidy); if( tidy_get_status($tidy) === 2){ // 2 is magic number for fatal error // http://www.php.net/manual/en/function.tidy-get-status.php return false; } $text = tidy_get_output($tidy); return true; } /** * Return javascript code to be used with autocomplete (jquery ui) * */ public static function AutoCompleteValues($GetUrl=true,$options = array()){ global $gp_index; $options += array( 'admin_vals' => true, 'var_name' => 'gptitles' ); //internal link array $array = array(); foreach($gp_index as $slug => $id){ $label = \gp\tool::GetLabel($slug); $label = str_replace( array('<','>','"',''','&'), array('<','>','"',"'",'&') , $label); if( $GetUrl ){ $slug = \gp\tool::GetUrl($slug,'',false); $slug = rawurldecode($slug); } $array[] = array($label,$slug); } if( $options['admin_vals'] && class_exists('admin_tools') ){ $scripts = \gp\admin\Tools::AdminScripts(); foreach($scripts as $url => $info){ if( !isset($info['label']) ){ continue; } if( $GetUrl ){ $url = \gp\tool::GetUrl($url,'',false); $url = rawurldecode($url); } $array[] = array($info['label'],$url); } } $code = json_encode($array); if( $options['var_name'] ){ $code = 'var '.$options['var_name'].' = '.$code.';'; } return $code; } public static function PrepAutoComplete(){ global $page; \gp\tool::LoadComponents('autocomplete'); $page->head_js[] = '/include/js/autocomplete.js'; } /** * Use ckeditor for to edit content * * configuration options * - http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html */ public static function UseCK($contents,$name='gpcontent',$options=array()){ global $page, $dataDir; $options += array('rows'=>'20','cols'=>'50'); echo "\n\n"; echo '
'; $page->head .= "\n".''; $page->head .= "\n".''; \gp\tool::LoadComponents('autocomplete'); $page->head_script .= self::AutoCompleteValues(true); ob_start(); echo "\n\n"; // extra plugins $config = self::CKConfig( $options, 'json', $plugins ); foreach($plugins as $plugin => $plugin_path){ echo 'CKEDITOR.plugins.addExternal('.json_encode($plugin).','.json_encode($plugin_path).');'; echo "\n"; } echo '$(".CKEDITAREA").each(function(){'; echo 'CKEDITOR.replace( this, '.$config.' );'; echo 'CKEDITOR.on("instanceReady", function(evt){'; /* echo 'console.log("triggered editor:loaded event with ", { section: evt.editor.element["$"], section_type: "other", label: evt.editor.name });'; */ echo '$(document).trigger("editor:loaded", { editor: evt.editor, section: evt.editor.element["$"], section_type: "other", label: evt.editor.name });'; echo '});'; echo '});'; echo "\n\n"; $page->jQueryCode .= ob_get_clean(); } public static function CKAdminConfig(){ static $cke_config; //get ckeditor configuration set by users if( !is_array($cke_config) ){ $cke_config = \gp\tool\Files::Get('_ckeditor/config','cke_config'); if( !$cke_config ){ $cke_config = array(); } $cke_config += array('plugins'=>array(),'custom_config'=>array()); } return $cke_config; } /** * CKEditor configuration settings * Any settings here take precedence over settings in configuration files defined by the customConfig setting * Configuration precedence: (1) User (2) Addon (3) $options (4) CMS * */ public static function CKConfig( $options = array(), $config_name = 'config', &$plugins = array() ){ global $config; $plugins = array(); // 4) CMS defaults $defaults = array( //'customConfig' => \gp\tool::GetDir('/include/js/ckeditor_config.js'), 'skin' => 'moono-lisa', 'browser' => true, //not actually a ckeditor configuration value, but we're keeping it now for reverse compat 'smiley_path' => \gp\tool::GetDir('/include/thirdparty/ckeditor/plugins/smiley/images/'), 'height' => 300, 'contentsCss' => \gp\tool::GetDir('/include/css/ckeditor_contents.css'), 'fontSize_sizes' => 'Smaller/smaller;Normal/;Larger/larger;8/8px;9/9px;10/10px;11/11px;12/12px;14/14px;16/16px;18/18px;20/20px;22/22px;24/24px;26/26px;28/28px;36/36px;48/48px;72/72px', 'ignoreEmptyParagraph' => true, 'entities_latin' => false, 'entities_greek' => false, 'scayt_autoStartup' => false, 'disableNativeSpellChecker' => false, 'FillEmptyBlocks' => false, 'autoParagraph' => false, 'extraAllowedContent' => 'iframe[align,frameborder,height,longdesc,marginheight,marginwidth,name,sandbox,scrolling,seamless,src,srcdoc,width];script[async,charset,defer,src,type,xml]; *[accesskey,contenteditable,contextmenu,dir,draggable,dropzone,hidden,id,lang,spellcheck,style,tabindex,title,translate](*)', 'toolbar' => array( array('Sourcedialog','Templates','ShowBlocks','Undo','Redo','RemoveFormat'), //,'Maximize' does not work well array('Cut','Copy','Paste','PasteText','PasteFromWord','SelectAll','Find','Replace'), array('HorizontalRule','Smiley','SpecialChar','PageBreak','TextColor','BGColor'), array('Link','Unlink','Anchor','Image','Table'), array('Format','Font','FontSize'), array('JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock','NumberedList','BulletedList','Outdent','Indent'), array('Bold','Italic','Underline','Strike','Blockquote','Subscript','Superscript','About') ), ); if( $config['langeditor'] == 'inherit' ){ $defaults['language'] = $config['language']; }else{ $defaults['language'] = $config['langeditor']; } // 3) $options $options += $defaults; // 2) Addon settings $options = \gp\tool\Plugins::Filter('CKEditorConfig',array($options)); // $options['config_key'] = 'config_value'; $plugins = \gp\tool\Plugins::Filter('CKEditorPlugins',array($plugins)); // $plugins['plugin_name'] = 'path_to_plugin_folder'; // 1) User $admin_config = self::CKAdminConfig(); foreach($admin_config['plugins'] as $plugin => $plugin_info){ $plugins[$plugin] = \gp\tool::GetDir('/data/_ckeditor/'.$plugin.'/'); } // extra plugins $extra_plugins = array_keys($plugins); if( array_key_exists('extraPlugins',$options) ){ $extra_plugins = array_merge( $extra_plugins, explode(',',$options['extraPlugins']) ); } $options = $admin_config['custom_config'] + $options; $options['extraPlugins'] = implode(',',$extra_plugins); //browser paths if( $options['browser'] ){ $options['filebrowserBrowseUrl'] = \gp\tool::GetUrl('Admin/Browser').'?type=all'; $options['filebrowserImageBrowseUrl'] = \gp\tool::GetUrl('Admin/Browser').'?dir=%2Fimage'; unset($options['browser']); } switch( $config_name ){ case 'array': return $options; case 'json': return json_encode($options); } return '$.extend('.$config_name.', '.json_encode($options).');'; } /** * Get the default content for the specified content type * @static * @since 3.6 * */ public static function DefaultContent($type='text', $heading = 'Lorem Ipsum' ){ global $langmessage; $section = array(); $section['type'] = $type; $section['content'] = ''; switch($type){ case 'include': $section['gp_label'] = $langmessage['File Include']; break; case 'gallery': $section['gp_label'] = $langmessage['Image Gallery']; $section['content'] = ''; break; case 'wrapper_section': $section['gp_label'] = $langmessage['Section Wrapper']; $section['content'] = ''; $section['gp_color'] = '#555'; $section['contains_sections'] = 0; break; case 'image': $section['gp_label'] = $langmessage['Image']; $section['nodeName'] = 'img'; $section['attributes']['src'] = '/include/imgs/default_image.jpg'; $section['attributes']['alt'] = pathinfo( $section['attributes']['src'] , PATHINFO_FILENAME ); $section['attributes']['width'] = '400px'; $section['attributes']['height'] = '300px'; break; case 'text': $section['gp_label'] = $langmessage['editable_text']; $section['content'] = '

'.strip_tags($heading).'

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

'; break; default: $section['content'] = '

'.strip_tags($heading).'

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

'; break; } $content = \gp\tool\Plugins::Filter('GetDefaultContent',array($section['content'],$type)); if( is_array($content) ){ $section = $content + $section; }else{ $section['content'] = $content; } $section += array('attributes'=>array()); $section['attributes'] += array('class'=>''); return $section; } /** * Return an array * */ public static function SectionFromPost( &$existing_section, $section_num, $title, $file_stats ){ global $page, $gpAdmin; $section_before = $existing_section; $type = $existing_section['type']; $save_this = false; switch($type){ case 'text': $save_this = true; self::SectionFromPost_Text( $existing_section ); break; case 'gallery': $save_this = true; self::SectionFromPost_Gallery( $existing_section ); break; case 'include': $save_this = self::SectionFromPost_Include( $existing_section, $section_num, $title, $file_stats ); break; case 'image': $save_this = self::SectionFromPost_Image( $existing_section ); break; } //make sure $existing_section is still an array $type_check = gettype($existing_section); if( $type_check !== 'array' ){ trigger_error('$existing_section is '.$type_check.'. Array expected'); return false; } // Hack: SaveSection used $page->file_sections $page->file_sections[$section_num] = $existing_section; $save_this = \gp\tool\Plugins::Filter( 'SaveSection', array( $save_this, $section_num, $type) ); $existing_section = $page->file_sections[$section_num]; if( !$save_this ){ $page->file_sections[$section_num] = $existing_section = $section_before; } $page->file_sections[$section_num]['modified'] = time(); $page->file_sections[$section_num]['modified_by'] = $gpAdmin['username']; return $save_this; } /** * Get the posted content for an image area * @return bool * */ public static function SectionFromPost_Image( &$section, $dest_dir = '/data/_resized/img_type/' ){ global $page, $dataDir, $dirPrefix, $langmessage; $page->ajaxReplace = array(); //source file if( !empty($_REQUEST['src']) ){ $source_file_rel = rawurldecode($_REQUEST['src']); if( !empty($dirPrefix) ){ $len = strlen($dirPrefix); $source_file_rel = substr($source_file_rel,$len); } }elseif( !empty($_REQUEST['file']) ){ $source_file_rel = $_REQUEST['file']; }else{ msg($langmessage['OOPS']); return false; } $source_file_rel = '/'.ltrim($source_file_rel,'/'); $source_file_full = $dataDir.$source_file_rel; if( !file_exists($source_file_full) ){ msg($langmessage['OOPS'].' (Source file not found)'); return false; } $src_img = \gp\tool\Image::getSrcImg($source_file_full); if( $src_img === false ){ msg($langmessage['OOPS'].' (Couldn\'t create image [1])'); return false; } //size and position variables $orig_w = imagesx($src_img); $orig_h = imagesy($src_img); $posx = self::ReqNumeric('posx',0); $posy = self::ReqNumeric('posy',0); $width = self::ReqNumeric('width',$orig_w); $height = self::ReqNumeric('height',$orig_h); //check to see if the image needs to be resized if( $posx == 0 && $posy == 0 && $width == $orig_w && $height == $orig_h ){ $section['attributes']['src'] = $source_file_rel; $section['attributes']['alt'] = $_REQUEST['alt']; $section['attributes']['height'] = $height; $section['attributes']['width'] = $width; $section['orig_src'] = $_REQUEST['src']; $section['posx'] = 0; $section['posy'] = 0; return true; } //destination file $name = basename($source_file_rel); $parts = explode('.',$name); //remove the time portion of the filename if( count($parts) > 1 ){ $time_part = array_pop($parts); if( !ctype_digit($time_part) ){ $parts[] = $time_part; } } $name = implode('.',$parts); $time = self::ReqTime(); $dest_img_rel = $dest_dir.$name.'.'.$time.'.png'; $dest_img_full = $dataDir.$dest_img_rel; //make sure the folder exists if( !\gp\tool\Files::CheckDir( dirname($dest_img_full) ) ){ msg($langmessage['OOPS'].' (Couldn\'t create directory)'); return false; } if( !\gp\tool\Image::createImg($src_img, $dest_img_full, $posx, $posy, 0, 0, $orig_w, $orig_h, $orig_w, $orig_h, $width, $height, $source_file_full) ){ msg($langmessage['OOPS'].' (Couldn\'t create image [2])'); return false; } $section['attributes']['src'] = $dest_img_rel; $section['attributes']['alt'] = $_REQUEST['alt']; $section['attributes']['height'] = $height; $section['attributes']['width'] = $width; $section['orig_src'] = $_REQUEST['src']; $section['posx'] = $posx; $section['posy'] = $posy; \gp\admin\Content\Uploaded::CreateThumbnail($dest_img_full); return true; } /** * Return the value in the request if it's a numeric value * */ public static function ReqNumeric($key, $value){ if( isset($_REQUEST[$key]) && is_numeric($_REQUEST[$key]) ){ $value = $_REQUEST[$key]; } return $value; } /** * Get the timestamp used by the current request * */ public static function ReqTime(){ if( isset($_REQUEST['time']) && ctype_digit($_REQUEST['time']) ){ return $_REQUEST['time']; } if( isset($_REQUEST['req_time']) && ctype_digit($_REQUEST['req_time']) ){ return $_REQUEST['req_time']; } return time(); } /** * Get the posted content for a text area * */ public static function SectionFromPost_Text( &$section ){ global $config; $content =& $_POST['gpcontent']; \gp\tool\Files::cleanText($content); $section['content'] = $content; if( $config['resize_images'] ){ self::ResizeImages( $section['content'], $section['resized_imgs'] ); } return true; } /** * Save Gallery Content * */ public static function SectionFromPost_Gallery( &$section ){ if( empty($_POST['images']) ){ $section['content'] = ''; return; } $rel_id = 'gallery_'.time(); ob_start(); echo ''; $section['content'] = ob_get_clean(); $section['images'] = $_POST['images']; $section['captions'] = $_POST['captions']; $section['attributes']['class'] = $_POST['attributes']['class']; } /** * Include Editing * */ public static function IncludeOptions(){ global $page, $langmessage, $config, $gp_index, $dataDir; $include_options = []; //gadget include autocomplete if( isset($config['gadgets']) ){ foreach($config['gadgets'] as $uniq => $info){ $value = ['include_type'=>'gadget', 'content'=>$uniq]; $include_options[] = ['value'=>$value, 'label'=>$uniq, 'slug'=>'Gadget', 'filter_aide'=>'', 'icon'=>'fa-puzzle-piece']; } } //extra area include autocomplete $extra_area_files = scandir($dataDir . '/data/_extra') ?? []; foreach($extra_area_files as $extra_area){ $extra_area = \gp\admin\Content\Extra::AreaExists($extra_area); if( $extra_area === false ){ continue; } $value = ['include_type'=>'extra', 'content'=>$extra_area]; $include_options[] = ['value'=>$value, 'label'=>$extra_area, 'slug'=>$langmessage['theme_content'], 'filter_aide'=>'extra content', 'icon'=>'fa-cube']; } // pages foreach($gp_index as $slug => $id){ if( $page->gp_index == $id ){ continue; } $label = \gp\tool::GetLabel($slug); $label = str_replace( array('<', '>', '"', ''', '&'), array('<', '>', '"', "'", '&') , $label); $value = ['include_type'=>'file', 'content'=>$slug, 'index'=>$id ]; $include_options[] = ['value'=>$value, 'label'=>$label, 'slug'=> $langmessage['Page'] . ' /' . $slug, 'filter_aide'=>'page', 'icon'=>'fa-file-text-o']; } $hashes = []; foreach($include_options as $option){ $hash = sha1(json_encode($option['value'])); $hashes[$hash] = $option; } return $hashes; } public static function IncludeDialog( $section ){ global $page, $langmessage; $page->ajaxReplace = []; $include_options = self::IncludeOptions(); $scrollto = false; if( !array_key_exists('include_type',$section) || isset($section['index']) ){ $section['include_type'] = 'file'; } // generate dialog html ob_start(); echo '
'; echo '
'; echo ''; foreach($include_options as $hash => $option){ $checked = ''; if( $option['value']['include_type'] === $section['include_type'] && $option['value']['content'] === $section['content'] ){ $checked = 'checked'; $scrollto = $hash; } echo ''; } echo '
'; echo '
'; if( $scrollto ){ echo ''; } $content = ob_get_clean(); $page->ajaxReplace[] = array('gp_include_dialog','',$content); return false; } /** * Save an include section * */ public static function SectionFromPost_Include( &$existing_section, $section_num, $title, $file_stats ){ global $page, $langmessage, $gp_index, $config; $include_options = self::IncludeOptions(); $include = $_POST['include']; if( !array_key_exists($include,$include_options) ){ msg($langmessage['OOPS_TITLE']); return false; } // update include configuration unset($existing_section['index']); $existing_section = $include_options[$include]['value'] + $existing_section; // send replacement content $content = \gp\tool\Output\Sections::RenderSection( $existing_section, $section_num, $title, $file_stats ); $page->ajaxReplace[] = array('gp_include_content','',$content); return true; } /** * Display a form for creating a new directory * */ public static function NewDirForm(){ global $langmessage, $page; echo '
'; echo '

'.$langmessage['create_dir'].'

'; echo '
'; echo '

'; echo htmlspecialchars($_GET['dir']).'/'; echo ' '; echo '

'; echo '

'; if( !empty($_GET['dir']) ){ echo ' '; } echo ''; echo ' '; echo '

'; echo '
'; echo '
'; } /** * Perform various section editing commands * * @return bool true if $section should be saved * */ public static function SectionEdit( $cmd, &$section, $section_num, $title, $file_stats ){ global $langmessage; switch($cmd){ case 'include_dialog': self::IncludeDialog( $section ); return false; case 'inlineedit': \gp\tool\Output\Ajax::InlineEdit( $section ); die(); case 'save_inline': return self::SectionFromPost( $section, $section_num, $title, $file_stats ); } msg($langmessage['OOPS'].' (Unknown Command)'); return false; } /** * Output content for use with the inline image editor * */ public static function ImageEditor( $obj ){ global $langmessage, $page; //image options ob_start(); //edit current image echo '
'; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo '
'.$langmessage['Width'].''.$langmessage['Height'].'
'.$langmessage['Left'].''.$langmessage['Top'].'
'.$langmessage['Alternative Text'].'
'; echo '
'; //select image echo ''; $content = ob_get_clean(); $page->ajaxReplace = array(); $page->ajaxReplace[] = array('inner','#ckeditor_top',$content); $page->ajaxReplace[] = array('image_options_loaded','',''); //tell the script the images have been loaded } } } namespace{ class gp_edit extends \gp\tool\Editing{} }