/** * create a referenced image * * @param array of entity attributes (e.g., 'Content-Disposition') * @param string image actual content * @param array poster attributes * @param string the target anchor (e.g., 'article:123') * @param string reference of the object to be extended, if any * @return string reference to the created object, or NULL */ public static function submit_image($entity_headers, $content, $user, $anchor, $target = NULL) { global $context; // retrieve queue parameters list($server, $account, $password, $allowed, $match, $section, $options, $hooks, $prefix, $suffix) = $context['mail_queue']; // locate content-disposition foreach ($entity_headers as $header) { if (preg_match('/Content-Disposition/i', $header['name'])) { $content_disposition = $header['value']; break; } } // find file name in content-disposition $file_name = ''; if ($content_disposition && preg_match('/filename="*([a-zA-Z0-9\'\\(\\)\\+_,-\\.\\/:=\\? ]+)"*\\s*/i', $content_disposition, $matches)) { $file_name = $matches[1]; } // as an alternative, look in content-type if (!$file_name) { // locate content-type foreach ($entity_headers as $header) { if (preg_match('/Content-Type/i', $header['name'])) { $content_type = $header['value']; break; } } // find file name in content-type if ($content_type && preg_match('/name="*([a-zA-Z0-9\'\\(\\)\\+_,-\\.\\/:=\\? ]+)"*\\s*/i', $content_type, $matches)) { $file_name = $matches[1]; } } // as an alternative, look in content-description if (!$file_name) { // locate content-description foreach ($entity_headers as $header) { if (preg_match('/Content-Description/i', $header['name'])) { $content_description = $header['value']; break; } } // find file name in content-description $file_name = $content_description; } // sanity check if (!$file_name) { Logger::remember('agents/messages.php: No file name to use for submitted image'); return NULL; } // file size $file_size = strlen($content); // sanity check if ($file_size < 7) { Logger::remember('agents/messages.php: Short image skipped', $file_name); return NULL; } // sanity check if (!$anchor) { Logger::remember('agents/messages.php: No anchor to use for submitted image', $file_name); return NULL; } // get anchor data -- this is a mutable object $host = Anchors::get($anchor, TRUE); if (!is_object($host)) { Logger::remember('agents/messages.php: Unknown anchor ' . $anchor, $file_name); return NULL; } // create target folders $file_path = Files::get_path($anchor, 'images'); if (!Safe::make_path($file_path)) { Logger::remember('agents/messages.php: Impossible to create ' . $file_path); return NULL; } if (!Safe::make_path($file_path . '/thumbs')) { Logger::remember('agents/messages.php: Impossible to create ' . $file_path . '/thumbs'); return NULL; } $file_path = $context['path_to_root'] . $file_path . '/'; // save the entity in the file system if (!($file = Safe::fopen($file_path . $file_name, 'wb'))) { Logger::remember('agents/messages.php: Impossible to open ' . $file_path . $file_name); return NULL; } if (fwrite($file, $content) === FALSE) { Logger::remember('agents/messages.php: Impossible to write to ' . $file_path . $file_name); return NULL; } fclose($file); // get image information if (!($image_information = Safe::GetImageSize($file_path . $file_name))) { Safe::unlink($file_path . $file_name); Logger::remember('agents/messages.php: No image information in ' . $file_path . $file_name); return NULL; } // we accept only gif, jpeg and png if ($image_information[2] != 1 && $image_information[2] != 2 && $image_information[2] != 3) { Safe::unlink($file_path . $file_name); Logger::remember('agents/messages.php: Rejected image type for ' . $file_path . $file_name); return NULL; } // build a thumbnail $thumbnail_name = 'thumbs/' . $file_name; // do not stop on error include_once $context['path_to_root'] . 'images/image.php'; if (!Image::shrink($file_path . $file_name, $file_path . $thumbnail_name, FALSE, FALSE)) { Logger::remember('agents/messages.php: No thumbnail has been created for ' . $file_path . $file_name); } // resize the image where applicable if (Image::adjust($file_path . $file_name, FALSE)) { $file_size = Safe::filesize($file_path . $file_name); } // all details $details = array(); // image size if ($image_information = Safe::GetImageSize($file_path . $file_name)) { $details[] = i18n::c('Size') . ': ' . $image_information[0] . ' x ' . $image_information[1]; } // update image description $item = array(); $item['anchor'] = $anchor; $item['image_name'] = $file_name; $item['thumbnail_name'] = $thumbnail_name; $item['image_size'] = $file_size; $item['description'] = ''; if (isset($content_description) && $content_description != $file_name) { $item['description'] .= $content_description; } if (@count($details)) { $item['description'] .= "\n\n" . '<p class="details">' . implode("<br />\n", $details) . "</p>\n"; } $item['edit_date'] = gmstrftime('%Y-%m-%d %H:%M:%S', time()); $item['edit_name'] = $user['nick_name']; $item['edit_id'] = $user['id']; $item['edit_address'] = $user['email']; // create an image record in the database include_once $context['path_to_root'] . 'images/images.php'; if (!($item['id'] = Images::post($item))) { Logger::remember('agents/messages.php: Impossible to save image ' . $item['image_name']); return NULL; } if ($context['debug_messages'] == 'Y') { Logger::remember('agents/messages.php: Messages::submit_image()', $item, 'debug'); } // insert the image in the anchor page $host->touch('image:create', $item['id'], TRUE); return 'image:' . $item['id']; }
/** * process one uploaded image * * @param string file name * @param string path to the file * @param boolean TRUE to not report on errors * @return boolean TRUE on correct processing, FALSE otherwise */ public static function upload($file_name, $file_path, $silent = FALSE) { global $context, $_REQUEST; // we accept only valid images if (!($image_information = Safe::GetImageSize($file_path . $file_name))) { if (!$silent) { Logger::error(sprintf(i18n::s('No image information in %s'), $file_path . $file_name)); } return FALSE; // we accept only gif, jpeg and png } elseif ($image_information[2] != 1 && $image_information[2] != 2 && $image_information[2] != 3) { if (!$silent) { Logger::error(sprintf(i18n::s('Rejected file type %s'), $file_name)); } return FALSE; // post-upload processing } else { // create folders $_REQUEST['thumbnail_name'] = 'thumbs/' . $file_name; // derive a thumbnail image if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'set_as_avatar') { Image::shrink($file_path . $file_name, $file_path . $_REQUEST['thumbnail_name'], TRUE, TRUE); } else { Image::shrink($file_path . $file_name, $file_path . $_REQUEST['thumbnail_name'], FALSE, TRUE); } // always limit the size of avatar images if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'set_as_avatar') { if (Image::adjust($file_path . $file_name, TRUE, 'avatar')) { $_REQUEST['image_size'] = Safe::filesize($file_path . $file_name); } // always limit the size of icon images } elseif (isset($_REQUEST['action']) && $_REQUEST['action'] == 'set_as_icon') { if (Image::adjust($file_path . $file_name, TRUE, 'avatar')) { $_REQUEST['image_size'] = Safe::filesize($file_path . $file_name); } // resize the image where applicable } elseif (isset($_REQUEST['automatic_process'])) { if (Image::adjust($file_path . $file_name, TRUE, 'standard')) { $_REQUEST['image_size'] = Safe::filesize($file_path . $file_name); } } return TRUE; } }
/** * check if a file or a path is writable * * @param string the target path * @return TRUE if the file can be written, FALSE otherwise */ public static function is_writable($path) { // translate the path $path = Safe::realpath($path); // the library function works on existing files only, and do not support safe mode if (file_exists($path) && is_callable('is_writable') && !is_writable($path)) { return FALSE; } // no complementary test on existing directory if (is_dir($path)) { return TRUE; } // complementary test uses the native PHP library if (!is_callable('fopen')) { return TRUE; } // test has to work even if file already exists if (!($handle = @fopen($path, 'ab'))) { return FALSE; } // clean up fclose($handle); // delete empty file, but don't kill files that exist previously if (Safe::filesize($path) < 10) { Safe::unlink($path); } // positive test return TRUE; }
if (is_dir($context['path_to_root'] . $file_path . '/' . $node)) { continue; } // an image has been found if (Image::upload($node, $context['path_to_root'] . $file_path . '/', TRUE)) { $count++; // resize the image where applicable Image::adjust($context['path_to_root'] . $file_path . '/' . $node, TRUE, 'standard'); // if the file does not exist yet if (!($item =& Images::get_by_anchor_and_name($anchor->get_reference(), $node))) { // create a new image record for this file $item = array(); $item['anchor'] = $anchor->get_reference(); $item['image_name'] = $node; $item['thumbnail_name'] = 'thumbs/' . $node; $item['image_size'] = Safe::filesize($file_path . '/' . $node); $item['use_thumbnail'] = 'A'; // ensure it is always displayed as a clickable small image $item['id'] = Images::post($item); } // ensure that the image is in anchor description field $nodes[$node] = $item['id']; } } Safe::closedir($handle); // embed uploaded images in alphabetical order ksort($nodes); foreach ($nodes as $name => $id) { $anchor->touch('image:create', $id); } }
/** * transform codes to html * * [php] * // build the page * $context['text'] .= ... * * // transform codes * $context['text'] = Codes::render($context['text']); * * // final rendering * render_skin(); * [/php] * * @link http://pureform.wordpress.com/2008/01/04/matching-a-word-characters-outside-of-html-tags/ * * @param string the input string * @return string the transformed string */ public static function render($text) { global $context; // the formatting code interface include_once $context['path_to_root'] . 'codes/code.php'; // streamline newlines, even if this has been done elsewhere $text = str_replace(array("\r\n", "\r"), "\n", $text); // prevent wysiwyg editors to bracket our own tags $text = preg_replace('#^<p>(\\[.+\\])</p>$#m', '$1', $text); // initialize only once static $patterns_map; if (!isset($patterns_map)) { if (Safe::filesize('codes/patterns.auto.php')) { include_once $context['path_to_root'] . 'codes/patterns.auto.php'; } else { // core patterns $patterns_map['|<!-- .* -->|i'] = ''; // remove HTML comments $patterns_map['|</h(\\d)>\\n+|i'] = '</h$1>'; // strip \n after title $patterns_map['/\\n[ \\t]*(From|To|cc|bcc|Subject|Date):(\\s*)/i'] = BR . '$1:$2'; // common message headers $patterns_map['/\\[escape\\](.*?)\\[\\/escape\\]/is'] = 'Codes::render_escaped'; // [escape]...[/escape] (before everything) $patterns_map['/\\[php\\](.*?)\\[\\/php\\]/is'] = 'Codes::render_pre_php'; // [php]...[/php] $patterns_map['/\\[snippet\\](.*?)\\[\\/snippet\\]/is'] = 'Codes::render_pre'; // [snippet]...[/snippet] $patterns_map['/(\\[page\\].*)$/is'] = ''; // [page] (provide only the first one) $patterns_map['/\\[(associate|member|anonymous|hidden|restricted|authenticated)\\](.*?)\\[\\/\\1\\]/is'] = 'Codes::render_hidden'; // [associate]...[/associate] $patterns_map['/\\[redirect=([^\\]]+?)\\]/is'] = 'Codes::render_redirect'; // [redirect=<link>] $patterns_map['/\\[execute=([^\\]]+?)\\]/is'] = 'Codes::render_execute'; // [execute=<name>] $patterns_map['/\\[parameter=([^\\]]+?)\\]/is'] = 'Codes::render_parameter'; // [parameter=<name>] $patterns_map['/\\[lang=([^\\]]+?)\\](.*?)\\[\\/lang\\]/is'] = 'Codes::render_lang'; // [lang=xy]...[/lang] $patterns_map['/\\[(images)=([^\\]]+?)\\]/i'] = 'Codes::render_object'; // [images=<ids>] (before other links) $patterns_map['/\\[(image)=([^\\]]+?)\\]/i'] = 'Codes::render_object'; // [image=<id>] $patterns_map['/##(\\S.*?\\S)##/is'] = '<code>$1</code>'; // ##...## $patterns_map['/\\[code\\](.*?)\\[\\/code\\]/is'] = '<code>$1</code>'; // [code]...[/code] $patterns_map['/\\[indent\\](.*?)\\[\\/(indent)\\]/is'] = 'Skin::build_block'; // [indent]...[indent] $patterns_map['/\\[quote\\](.*?)\\[\\/(quote)\\]/is'] = 'Skin::build_block'; // [quote]...[quote] $patterns_map['/\\[folded(?:=([^\\]]+?))?\\](.*?)\\[\\/(folded)\\]\\s*/is'] = 'Skin::build_box'; // [folded=title]...[/folded],[folded]...[/folded] $patterns_map['/\\[unfolded(?:=([^\\]]+?))?\\](.*?)\\[\\/(unfolded)\\]\\s*/is'] = 'Skin::build_box'; // [unfolded=title]...[/unfolded],[unfolded]...[/unfolded] $patterns_map['/\\[sidebar(?:=([^\\]]+?))?\\](.*?)\\[\\/(sidebar)\\]\\s*/is'] = 'Skin::build_box'; // [sidebar=title]...[/sidebar],[sidebar]...[/sidebar] $patterns_map['/\\[note\\](.*?)\\[\\/(note)\\]\\s*/is'] = 'Skin::build_block'; // [note]...[/note] $patterns_map['/\\[caution\\](.*?)\\[\\/(caution)\\]\\s*/is'] = 'Skin::build_block'; // [caution]...[/caution] $patterns_map['/\\[center\\](.*?)\\[\\/(center)\\]/is'] = 'Skin::build_block'; // [center]...[/center] $patterns_map['/\\[right\\](.*?)\\[\\/(right)\\]/is'] = 'Skin::build_block'; // [right]...[/right] $patterns_map['/\\[(go)=([^\\]]+?)\\]/i'] = 'Codes::render_object'; // [go=<name>] $patterns_map['/\\[(article\\.description)=([^\\]]+?)\\]/i'] = 'Codes::render_object'; // [article.description=<id>] $patterns_map['/\\[(article)=([^\\]]+?)\\]/i'] = 'Codes::render_object'; // [article=<id>] or [article=<id>, title] $patterns_map['/\\[(next)=([^\\]]+?)\\]/i'] = 'Codes::render_object'; // [next=<id>] $patterns_map['/\\[(previous)=([^\\]]+?)\\]/i'] = 'Codes::render_object'; // [previous=<id>] $patterns_map['/\\[random(?:=([^\\]]+?))?\\]/i'] = 'Codes::render_random'; // [random], [random=section:<id>] or [random=category:<id>] $patterns_map['/\\[(section)=([^\\]]+?)\\]/i'] = 'Codes::render_object'; // [section=<id>] or [section=<id>, title] $patterns_map['/\\[(category(?:\\.description)?)=([^\\]]+?)\\]\\n*/is'] = 'Codes::render_object'; // [category=<id>], [category=<id>, title] or [category.description=<id>] $patterns_map['/\\[(user)=([^\\]]+?)\\]/i'] = 'Codes::render_object'; // [user=<id>] $patterns_map['/\\[(users)=([^\\]]+?)\\]/i'] = 'Codes::render_users'; // [users=present] $patterns_map['/\\[(file|download)=([^\\]]+?)\\]/i'] = 'Codes::render_object'; // [file=<id>] or [file=<id>, title] or download=<id>] or [download=<id>, title] $patterns_map['/\\[(comment)=([^\\]]+?)\\]/i'] = 'Codes::render_object'; // [comment=<id>] or [comment=<id>, title] $patterns_map['/\\[(link)(?:=([^\\]]+?))?\\](.*?)\\[\\/link\\]/is'] = 'Codes::render_link'; // [link]url[/link] or [link=label]url[/link] $patterns_map['/\\[(button)=([^\\]]+?)\\](.*?)\\[\\/button\\]/is'] = 'Codes::render_link'; // [button=label]url[/button] $patterns_map['/\\[(button)=([^\\|]+?)\\|([^\\]]+?)]/is'] = 'Codes::render_link'; // [button=label|url] $patterns_map['/\\[(click)=([^\\|]+?)\\|([^\\]]+?)]/is'] = 'Codes::render_link'; // [click=label|url] $patterns_map['/(\\[)([^ ][^\\]\\|]+?[^ ])\\|([^ ][^\\]]+?[^ ])\\]/is'] = 'Codes::render_link'; // [label|url] $patterns_map['#(\\s)([a-z]+?://[a-z0-9_\\-\\.\\~\\/@&;:=%$\\?]+)#'] = 'Codes::render_link'; // make URL clickable $patterns_map['#(\\s)(www\\.[a-z0-9\\-]+\\.[a-z0-9_\\-\\.\\~]+(?:/[^,< \\r\\n\\)]*)?)#i'] = 'Codes::render_link'; // web server url $patterns_map['/http[s]*:\\/\\/www\\.youtube\\.com\\/watch\\?v=([a-zA-Z0-9_\\-]+)[a-zA-Z0-9_\\-&=]*/i'] = '<iframe class="youtube-player" type="text/html" width="445" height="364" src="http://www.youtube.com/embed/$1" frameborder="0"></iframe>'; // YouTube link $patterns_map['/http[s]*:\\/\\/youtu\\.be\\/([a-zA-Z0-9_\\-]+)/i'] = '<iframe class="youtube-player" type="text/html" width="445" height="364" src="http://www.youtube.com/embed/$1" frameborder="0"></iframe>'; // YouTube link too $patterns_map['/\\[clicks=([^\\]]+?)]/is'] = 'Codes::render_clicks'; // [clicks=url] // @TODO: put in extension $patterns_map['/\\[email\\](.*?)\\[\\/email\\]/is'] = 'Codes::render_email'; // [email]url[/email] $patterns_map['/(\\s)([a-z0-9_\\-\\.\\~]+?@[a-z0-9_\\-\\.\\~]+\\.[a-z0-9_\\-\\.\\~]+)/i'] = 'Codes::render_email'; // mail address $patterns_map['/\\[published(?:\\.([^\\]=]+?))?(?:=([^\\]]+?))?\\]\\n*/is'] = 'Codes::render_published'; // [published(.decorated)], [published=section:4029], [published.decorated=section:4029,x] $patterns_map['/\\[updated(?:\\.([^\\]=]+?))?(?:=([^\\]]+?))?\\]\\n*/is'] = 'Codes::render_updated'; // [updated(.decorated)], [updated(.decorated)=section:4029,x] $patterns_map['/\\[sections(?:\\.([^\\]=]+?))?(?:=([^\\]]+?))?\\]\\n*/is'] = 'Codes::render_sections'; // [sections(.decorated)] (site map), [sections(.decorated)=section:4029] (sub-sections), [sections.simple=self] (assigned) $patterns_map['/\\[categories(?:\\.([^\\]=]+?))?(?:=([^\\]]+?))?\\]\\n*/is'] = 'Codes::render_categories'; // [categories(.decorated)] (category tree), [categories(.decorated)=categories:4029] (sub-categories) $patterns_map['/\\[wikipedia=([^\\]]+?)\\]/is'] = 'Codes::render_wikipedia'; // [wikipedia=keyword] or [wikipedia=keyword, title] $patterns_map['/\\[be\\]/i'] = ' <img src="' . $context['url_to_root'] . 'skins/_reference/flags/be.gif" alt="belgian flag" /> '; // [be] belgian flag $patterns_map['/\\[ca\\]/i'] = ' <img src="' . $context['url_to_root'] . 'skins/_reference/flags/ca.gif" alt="canadian flag" /> '; // [ca] canadian flag $patterns_map['/\\[ch\\]/i'] = ' <img src="' . $context['url_to_root'] . 'skins/_reference/flags/ch.gif" alt="swiss flag" /> '; // [ch] swiss flag $patterns_map['/\\[de\\]/i'] = ' <img src="' . $context['url_to_root'] . 'skins/_reference/flags/de.gif" alt="german flag" /> '; // [de] german flag $patterns_map['/\\[en\\]/i'] = ' <img src="' . $context['url_to_root'] . 'skins/_reference/flags/gb.gif" alt="english flag" /> '; // [en] english flag $patterns_map['/\\[es\\]/i'] = ' <img src="' . $context['url_to_root'] . 'skins/_reference/flags/es.gif" alt="spanish flag" /> '; // [es] spanish flag $patterns_map['/\\[fr\\]/i'] = ' <img src="' . $context['url_to_root'] . 'skins/_reference/flags/fr.gif" alt="french flag" /> '; // [fr] french flag $patterns_map['/\\[gr\\]/i'] = ' <img src="' . $context['url_to_root'] . 'skins/_reference/flags/gr.gif" alt="greek flag" /> '; // [gr] greek flag $patterns_map['/\\[it\\]/i'] = ' <img src="' . $context['url_to_root'] . 'skins/_reference/flags/it.gif" alt="italian flag" /> '; // [it] italian flag $patterns_map['/\\[pt\\]/i'] = ' <img src="' . $context['url_to_root'] . 'skins/_reference/flags/pt.gif" alt="portugal flag" /> '; // [pt] portugal flag $patterns_map['/\\[us\\]/i'] = ' <img src="' . $context['url_to_root'] . 'skins/_reference/flags/us.gif" alt="us flag" /> '; // [us] us flag $patterns_map['/\\[clear\\]\\n*/i'] = ' <br style="clear: both;" /> '; // [clear] $patterns_map['/\\[nl\\]\\n*/i'] = BR; // [nl] new line // load formatting codes from files $dir = $context['path_to_root'] . 'codes/'; if ($handle = Safe::opendir($dir)) { while (false !== ($file = Safe::readdir($handle))) { if ($file == '..') { continue; } if ($file == '.') { continue; } //convention : //get file only begining with code_ if (!(substr($file, 0, 5) == 'code_')) { continue; } include_once $dir . $file; //get formatting code patterns from this class $classname = stristr($file, '.', TRUE); $code = new $classname(); $code->get_pattern($patterns_map); unset($code); } Safe::closedir($handle); } // cache all patterns in one unique file for next time Codes::save_patterns($patterns_map); } // end generating patterns from scratch } // end setting $patterns $text = Codes::process($text, $patterns_map); // done return $text; }
} // is the current file version ok? if (is_readable($context['path_to_root'] . $file) && ($result = Scripts::hash($file))) { // double check if ($attributes[1] == $result[1]) { continue; } } // we should have an updated file in the staging directory if (!is_readable($context['path_to_root'] . 'scripts/staging/' . $file)) { $box .= sprintf(i18n::s('ERROR: File %s is missing or corrupted.'), $file) . BR . "\n"; $missing_files++; continue; } // file should have some content --useful when space quota is full if (!Safe::filesize($context['path_to_root'] . 'scripts/staging/' . $file)) { $box .= sprintf(i18n::s('ERROR: File %s is missing or corrupted.'), $file) . BR . "\n"; $missing_files++; continue; } // ensure we have an exact copy $result = Scripts::hash('scripts/staging/' . $file); if ($attributes[1] != $result[1]) { $box .= sprintf(i18n::s('ERROR: File %s is missing or corrupted.'), $file) . BR . "\n"; $missing_files++; continue; } // report on the updated script $context['file_bar'] = array('scripts/browse.php?script=' . $file . '&store=staging' => i18n::s('Review'), 'scripts/compare.php?original=' . $file . '&updated=scripts/staging/' . $file . '&format=gdiff' => i18n::s('Diff')); $box .= $file . ' (' . $attributes[0] . ' ' . i18n::s('lines') . ') ' . Skin::build_list($context['file_bar'], 'menu') . BR . "\n"; $staging_files++;
// save updated content Safe::file_put_contents($name.'.jsmin', $text); // one file has been compressed $count++; } } }*/ // report to surfer if ($count) { $context['text'] .= sprintf(i18n::s('%d files have been minified.'), $count) . "\n"; } $context['text'] .= "</p>\n"; $context['text'] .= '<p>' . sprintf('%s has %d %s', 'included/browser/library_js_header.min.js', Safe::filesize($context['path_to_root'] . 'included/browser/library_js_header.min.js'), i18n::s('bytes')) . '</p>'; $context['text'] .= '<p>' . sprintf('%s has %d %s', 'included/browser/library_js_endpage.min.js', Safe::filesize($context['path_to_root'] . 'included/browser/library_js_endpage.min.js'), i18n::s('bytes')) . '</p>'; // display the execution time $time = round(get_micro_time() - $context['start_time'], 2); $context['text'] .= '<p>' . sprintf(i18n::s('Script terminated in %.2f seconds.'), $time) . '</p>'; // confirmation is required } else { // the confirmation question $context['text'] .= '<b>' . sprintf(i18n::s('You are about to compress and assemble Javascript files. Are you sure?'), $context['file_mask']) . "</b>\n"; // the menu for this page $context['text'] .= '<form method="post" action="' . $context['script_url'] . '"><p>' . Skin::build_submit_button(i18n::s('Yes, I do want to compress and assemble Javascript files')) . '<input type="hidden" name="action" value="confirm" />' . '</p></form>' . "\n"; // this may take several minutes $context['text'] .= '<p>' . i18n::s('When you will click on the button the server will be immediately requested to proceed. However, because of the so many things to do on the back-end, you may have to wait for minutes before getting a response displayed. Thank you for your patience.') . "</p>\n"; } // render the skin render_skin();