/** * Get the blog's media directory (and create it if necessary). * * If we're {@link is_admin_page() on an admin page}, it adds status messages. * @todo These status messages should rather go to a "syslog" and not be displayed to a normal user * * @param boolean Create the directory, if it does not exist yet? * @return string path string on success, false if the dir could not be created */ function get_media_dir($create = true) { global $media_path, $Messages, $Settings, $Debuglog; if (!$Settings->get('fm_enable_roots_blog')) { // User directories are disabled: $Debuglog->add('Attempt to access blog media dir, but this feature is globally disabled', 'files'); return false; } switch ($this->media_location) { case 'default': $mediadir = get_canonical_path($media_path . 'blogs/' . $this->urlname . '/'); break; case 'subdir': $mediadir = get_canonical_path($media_path . $this->media_subdir); break; case 'custom': $mediadir = get_canonical_path($this->media_fullpath); break; case 'none': default: $Debuglog->add('Attempt to access blog media dir, but this feature is disabled for this blog', 'files'); return false; } // TODO: use a File object here (to access perms, ..) when FileCache::get_by_path() is provided. if ($create && !is_dir($mediadir)) { // TODO: Link to some help page(s) with errors! if (!is_writable(dirname($mediadir))) { // add error if (is_admin_page()) { $Messages->add(sprintf(T_("The blog's media directory «%s» could not be created, because the parent directory is not writable or does not exist."), rel_path_to_base($mediadir)) . get_manual_link('media_file_permission_errors'), 'error'); } return false; } elseif (!@mkdir($mediadir)) { // add error if (is_admin_page()) { $Messages->add(sprintf(T_("The blog's media directory «%s» could not be created."), rel_path_to_base($mediadir)) . get_manual_link('directory_creation_error'), 'error'); } return false; } else { // chmod and add note: $chmod = $Settings->get('fm_default_chmod_dir'); if (!empty($chmod)) { @chmod($mediadir, octdec($chmod)); } if (is_admin_page()) { $Messages->add(sprintf(T_("The blog's media directory «%s» has been created with permissions %s."), rel_path_to_base($mediadir), substr(sprintf('%o', fileperms($mediadir)), -3)), 'success'); } } } return $mediadir; }
/** * Register a plugin. * * This handles the indexes, dynamically unregisters a Plugin that does not exist (anymore) * and instantiates the Plugin's (User)Settings. * * @access protected * @param string name of plugin class to instantiate and register * @param int ID in database (0 if not installed) * @param int Priority in database (-1 to keep default) * @param string Path of the .php class file of the plugin. * @param boolean Must the plugin exist (classfile_path and classname)? * This is used internally to be able to unregister a non-existing plugin. * @return Plugin Plugin ref to newly created plugin; string in case of error */ function ®ister($classname, $ID = 0, $priority = -1, $classfile_path = NULL, $must_exists = true) { global $Debuglog, $Messages, $Timer; if ($ID && isset($this->index_ID_Plugins[$ID])) { debug_die('Tried to register already registered Plugin (ID ' . $ID . ')'); // should never happen! } $Timer->resume('plugins_register'); if (empty($classfile_path)) { $classfile_path = $this->get_classfile_path($classname); } $Debuglog->add('register(): ' . $classname . ', ID: ' . $ID . ', priority: ' . $priority . ', classfile_path: [' . $classfile_path . ']', 'plugins'); if (!is_readable($classfile_path)) { // Plugin file not found! if ($must_exists) { $r = 'Plugin class file [' . rel_path_to_base($classfile_path) . '] is not readable!'; $Debuglog->add($r, array('plugins', 'error')); // Get the Plugin object (must not exist) $Plugin =& $this->register($classname, $ID, $priority, $classfile_path, false); $this->plugin_errors[$ID]['register'] = $r; $this->set_Plugin_status($Plugin, 'broken'); // unregister: if ($this->unregister($Plugin)) { $Debuglog->add('Unregistered plugin [' . $classname . ']!', array('plugins', 'error')); } else { $Plugin->name = $Plugin->classname; // use the classname instead of "unnamed plugin" $Timer->pause('plugins_register'); return $Plugin; } $Timer->pause('plugins_register'); return $r; } } elseif (!class_exists($classname)) { $Debuglog->add('Loading plugin class file: ' . $classname, 'plugins'); require_once $classfile_path; } if (!class_exists($classname)) { // the given class does not exist if ($must_exists) { $r = sprintf('Plugin class for «%s» in file «%s» not defined.', $classname, rel_path_to_base($classfile_path)); $Debuglog->add($r, array('plugins', 'error')); // Get the Plugin object (must not exist) fp> why is this recursive? $Plugin =& $this->register($classname, $ID, $priority, $classfile_path, false); $this->plugin_errors[$ID]['register'] = $r; $this->set_Plugin_status($Plugin, 'broken'); // unregister: if ($this->unregister($Plugin)) { $Debuglog->add('Unregistered plugin [' . $classname . ']!', array('plugins', 'error')); } else { $Plugin->name = $Plugin->classname; // use the classname instead of "unnamed plugin" $Timer->pause('plugins_register'); return $Plugin; } $Timer->pause('plugins_register'); return $r; } else { $Plugin = new Plugin(); // COPY ! $Plugin->code = NULL; } } else { $Plugin = new $classname(); // COPY ! } $Plugin->classfile_path = $classfile_path; // Tell him his ID :) if ($ID == 0) { $Plugin->ID = --$this->smallest_internal_ID; } else { $Plugin->ID = $ID; if ($ID > 0) { // Properties from T_plugins // Code $Plugin->code = $this->index_ID_rows[$Plugin->ID]['plug_code']; // Status $Plugin->status = $this->index_ID_rows[$Plugin->ID]['plug_status']; } } // Tell him his name :) $Plugin->classname = $classname; // Tell him his priority: if ($priority > -1) { $Plugin->priority = $priority; } if (empty($Plugin->name)) { $Plugin->name = $Plugin->classname; } // Memorizes Plugin in code hash array: if (!empty($this->index_code_ID[$Plugin->code]) && $this->index_code_ID[$Plugin->code] != $Plugin->ID) { // The plugin's default code is already in use! $Plugin->code = NULL; } else { $this->index_code_Plugins[$Plugin->code] =& $Plugin; $this->index_code_ID[$Plugin->code] =& $Plugin->ID; } $this->index_ID_Plugins[$Plugin->ID] =& $Plugin; if (!in_array($Plugin->ID, $this->sorted_IDs)) { // not in our sort index yet $this->sorted_IDs[] =& $Plugin->ID; } // Init the Plugins (User)Settings members. $this->init_settings($Plugin); // Stuff only for real/existing Plugins (which exist in DB): if ($Plugin->ID > 0) { $tmp_params = array('db_row' => $this->index_ID_rows[$Plugin->ID], 'is_installed' => true); if ($Plugin->PluginInit($tmp_params) === false && $this->unregister($Plugin)) { $Debuglog->add('Unregistered plugin, because PluginInit returned false.', 'plugins'); $Plugin = ''; } elseif ($Plugin->version != $this->index_ID_rows[$Plugin->ID]['plug_version'] && $must_exists) { // Version has changed since installation or last update $db_deltas = array(); // Tell the Plugin that we've detected a version change: $tmp_params = array('old_version' => $this->index_ID_rows[$Plugin->ID]['plug_version'], 'db_row' => $this->index_ID_rows[$Plugin->ID]); if ($this->call_method($Plugin->ID, 'PluginVersionChanged', $tmp_params) === false) { $Debuglog->add('Set plugin status to "needs_config", because PluginVersionChanged returned false.', 'plugins'); $this->set_Plugin_status($Plugin, 'needs_config'); if ($this->unregister($Plugin)) { // only unregister the Plugin, if it's not the admin list's class: $Plugin = ''; } } else { // Check if there are DB deltas required (also when downgrading!), without excluding any query type: load_funcs('_core/model/db/_upgrade.funcs.php'); $db_deltas = db_delta($Plugin->GetDbLayout()); if (empty($db_deltas)) { // No DB changes needed, update (bump or decrease) the version global $DB; $Plugins_admin =& get_Plugins_admin(); // Update version in DB: $DB->query(' UPDATE T_plugins SET plug_version = ' . $DB->quote($Plugin->version) . ' WHERE plug_ID = ' . $Plugin->ID); // Update "plug_version" in indexes: $this->index_ID_rows[$Plugin->ID]['plug_version'] = $Plugin->version; if (isset($Plugins_admin->index_ID_rows[$Plugin->ID])) { $Plugins_admin->index_ID_rows[$Plugin->ID]['plug_version'] = $Plugin->version; } // Remove any prerenderered content for the Plugins renderer code: if (!empty($Plugin->code)) { $DB->query(' DELETE FROM T_items__prerendering WHERE itpr_renderers REGEXP "^(.*\\.)?' . $DB->escape($Plugin->code) . '(\\..*)?$"'); } // Detect new events (and delete obsolete ones - in case of downgrade): if ($Plugins_admin->save_events($Plugin, array())) { $this->load_events(); // re-load for the current request } $Debuglog->add('Version for ' . $Plugin->classname . ' changed from ' . $this->index_ID_rows[$Plugin->ID]['plug_version'] . ' to ' . $Plugin->version, 'plugins'); } else { // If there are DB schema changes needed, set the Plugin status to "needs_config" // TODO: automatic upgrade in some cases (e.g. according to query types)? $this->set_Plugin_status($Plugin, 'needs_config'); $Debuglog->add('Set plugin status to "needs_config", because version DB schema needs upgrade.', 'plugins'); if ($this->unregister($Plugin)) { // only unregister the Plugin, if it's not the admin list's class: $Plugin = ''; } } } } if ($Plugin && isset($this->index_ID_rows[$Plugin->ID])) { if ($this->index_ID_rows[$Plugin->ID]['plug_name'] !== NULL) { $Plugin->name = $this->index_ID_rows[$Plugin->ID]['plug_name']; } if ($this->index_ID_rows[$Plugin->ID]['plug_shortdesc'] !== NULL) { $Plugin->short_desc = $this->index_ID_rows[$Plugin->ID]['plug_shortdesc']; } } } else { // This gets called for non-installed Plugins: // We're not instantiating UserSettings/Settings, since that needs a DB backend. $tmp_params = array('db_row' => array(), 'is_installed' => false); if ($Plugin->PluginInit($tmp_params) === false && $this->unregister($Plugin)) { $Debuglog->add('Unregistered plugin, because PluginInit returned false.', 'plugins'); $Plugin = ''; } } $Timer->pause('plugins_register'); return $Plugin; }
/** * Define here default collection/blog settings that are to be made available in the backoffice. * * @return array See {@link Plugin::GetDefaultSettings()}. */ function get_coll_setting_definitions(&$params) { $r = array('coll_text' => array('label' => 'Image text', 'size' => 70, 'defaultvalue' => $this->Settings->get('text'), 'note' => T_('The text to write on the image.')), 'coll_font' => array('label' => 'Font file name', 'size' => 30, 'defaultvalue' => $this->Settings->get('font'), 'note' => sprintf(T_('You can upload your own fonts to the plugin\'s font directory (%s), then use the filename here. By default "%s" is used.'), rel_path_to_base($this->fonts_dir), rel_path_to_base($this->get_default_font()))), 'coll_font_size' => array('label' => 'Font size', 'type' => 'select', 'options' => array(6 => 6, 8 => 8, 10 => 10, 12 => 12, 14 => 14, 16 => 16, 18 => 18, 20 => 20, 22 => 22, 24 => 24, 26 => 26, 28 => 28, 30 => 30, 32 => 32, 34 => 34, 36 => 36, 38 => 38, 40 => 40, 42 => 42, 44 => 44, 46 => 46, 48 => 48, 50 => 50, 52 => 52, 54 => 54, 56 => 56, 58 => 58, 60 => 60, 62 => 62, 64 => 64, 66 => 66, 68 => 68), 'defaultvalue' => $this->Settings->get('font_size'), 'note' => '')); return $r; }
// Close button: $Form->global_icon(T_('Close info!'), 'close', regenerate_url()); $Form->begin_form('fform', ' '); $Form->hidden('ctrl', 'plugins'); $Form->begin_fieldset('Plugin info', array('class' => 'fieldset')); $Form->info_field(T_('Name'), $edit_Plugin->name); $Form->info_field(T_('Code'), empty($edit_Plugin->code) ? ' - ' : $edit_Plugin->code, array('note' => T_('This 8-32 character code identifies the plugin when it needs to be called directly and specifically. This is especially useful for renderer plugins and widgets (SkinTags).'))); $Form->info_field(T_('Short desc'), $edit_Plugin->short_desc); $Form->info_field(T_('Long desc'), $edit_Plugin->long_desc); if ($edit_Plugin->ID > 0) { // do not display ID for non registered Plugins $Form->info_field(T_('ID'), $edit_Plugin->ID); } $Form->info_field(T_('Version'), $edit_Plugin->version); $Form->info_field(T_('Classname'), $edit_Plugin->classname); $Form->info_field(T_('Class file'), rel_path_to_base($edit_Plugin->classfile_path)); // Help icons (to homepage and README.html), if available: $help_icons = array(); if ($help_www = $edit_Plugin->get_help_link('$help_url')) { $help_icons[] = $help_www; } if (!empty($help_icons)) { $Form->info_field(T_('Help'), implode(' ', $help_icons)); } if ($edit_Plugin->ID < 1) { // add "Install NOW" submit button (if not already installed) $registrations = $admin_Plugins->count_regs($edit_Plugin->classname); if (!isset($edit_Plugin->number_of_installs) || $admin_Plugins->count_regs($edit_Plugin->classname) < $edit_Plugin->number_of_installs) { // number of installations are not limited or not reached yet $Form->add_crumb('plugin'); $Form->hidden('action', 'install');
echo rawurlencode($loop_Plugin->classname) . '&' . url_crumb('plugin'); ?> "><?php echo T_('Install'); if ($registrations) { // This plugin is already installed echo ' #' . ($registrations + 1); } ?> </a>] <?php } $Table->display_col_end(); $Table->display_line_end(); evo_flush(); // free memory: $AvailablePlugins->unregister($loop_Plugin); } // BODY END: $Table->display_body_end(); $Table->display_list_end(); // Note about how to make plugins available for installation. // It should make clear that the above list are not all available plugins (e.g. through an online channel)! global $plugins_path; echo '<p>'; echo T_('The above plugins are those already installed into your "plugins" directory.'); echo "</p>\n<p>"; printf(T_('You can find more plugins online at %s or other channels.'), '<a href="http://plugins.b2evolution.net/">plugins.b2evolution.net</a>'); echo "</p>\n<p>"; printf(T_('To make a plugin available for installation, extract it into the "%s" directory on the server.'), rel_path_to_base($plugins_path)); echo '</p>';
/** * Template tag. Include a sub-template at the current position * */ function skin_include($template_name, $params = array()) { if (is_ajax_content($template_name)) { // When we request ajax content for results table we need to hide wrapper data (header, footer & etc) return; } global $skins_path, $ads_current_skin_path, $disp; // Globals that may be needed by the template: global $Blog, $MainList, $Item; global $Plugins, $Skin; global $current_User, $Hit, $Session, $Settings; global $skin_url, $htsrv_url, $htsrv_url_sensitive; global $samedomain_htsrv_url, $secure_htsrv_url; global $credit_links, $skin_links, $francois_links, $fplanque_links, $skinfaktory_links; /** * @var Log */ global $Debuglog; global $Timer; $timer_name = 'skin_include(' . $template_name . ')'; $Timer->resume($timer_name); if ($template_name == '$disp$') { // This is a special case. // We are going to include a template based on $disp: // Default display handlers: $disp_handlers = array('disp_404' => '_404_not_found.disp.php', 'disp_arcdir' => '_arcdir.disp.php', 'disp_catdir' => '_catdir.disp.php', 'disp_comments' => '_comments.disp.php', 'disp_feedback-popup' => '_feedback_popup.disp.php', 'disp_help' => '_help.disp.php', 'disp_login' => '_login.disp.php', 'disp_register' => '_register.disp.php', 'disp_activateinfo' => '_activateinfo.disp.php', 'disp_lostpassword' => '_lostpassword.disp.php', 'disp_mediaidx' => '_mediaidx.disp.php', 'disp_msgform' => '_msgform.disp.php', 'disp_threads' => '_threads.disp.php', 'disp_contacts' => '_threads.disp.php', 'disp_messages' => '_messages.disp.php', 'disp_page' => '_page.disp.php', 'disp_postidx' => '_postidx.disp.php', 'disp_posts' => '_posts.disp.php', 'disp_profile' => '_profile.disp.php', 'disp_avatar' => '_profile.disp.php', 'disp_pwdchange' => '_profile.disp.php', 'disp_userprefs' => '_profile.disp.php', 'disp_subs' => '_profile.disp.php', 'disp_search' => '_search.disp.php', 'disp_single' => '_single.disp.php', 'disp_sitemap' => '_sitemap.disp.php', 'disp_user' => '_user.disp.php', 'disp_users' => '_users.disp.php', 'disp_edit' => '_edit.disp.php', 'disp_edit_comment' => '_edit_comment.disp.php', 'disp_closeaccount' => '_closeaccount.disp.php', 'disp_module_form' => '_module_form.disp.php', 'disp_useritems' => '_useritems.disp.php', 'disp_usercomments' => '_usercomments.disp.php'); // Add plugin disp handlers: if ($disp_Plugins = $Plugins->get_list_by_event('GetHandledDispModes')) { foreach ($disp_Plugins as $disp_Plugin) { // Go through whole list of plugins providing disps if ($plugin_modes = $Plugins->call_method($disp_Plugin->ID, 'GetHandledDispModes', $disp_handlers)) { // plugin handles some custom disp modes foreach ($plugin_modes as $plugin_mode) { $disp_handlers[$plugin_mode] = '#' . $disp_Plugin->ID; } } } } // Allow skin overrides as well as additional disp modes (This can be used in the famou shopping cart scenario...) $disp_handlers = array_merge($disp_handlers, $params); if (!isset($disp_handlers['disp_' . $disp])) { global $Messages; $Messages->add(sprintf('Unhandled disp type [%s]', htmlspecialchars($disp))); $Messages->display(); $Timer->pause($timer_name); $disp = '404'; } $template_name = $disp_handlers['disp_' . $disp]; if (empty($template_name)) { // The caller asked not to display this handler $Timer->pause($timer_name); return; } } $disp_handled = false; if ($template_name[0] == '#') { // This disp mode is handled by a plugin: $plug_ID = substr($template_name, 1); $disp_params = array('disp' => $disp); $Plugins->call_method($plug_ID, 'HandleDispMode', $disp_params); $disp_handled = true; } elseif (file_exists($ads_current_skin_path . $template_name)) { // The skin has a customized handler, use that one instead: $file = $ads_current_skin_path . $template_name; $Debuglog->add('skin_include (' . ($Item ? 'Item #' . $Item->ID : '-') . '): ' . rel_path_to_base($file), 'skins'); require $file; $disp_handled = true; } elseif (file_exists($skins_path . $template_name)) { // Use the default template: global $Debuglog; $file = $skins_path . $template_name; $Debuglog->add('skin_include (' . ($Item ? 'Item #' . $Item->ID : '-') . '): ' . rel_path_to_base($file), 'skins'); require $file; $disp_handled = true; } if (!$disp_handled) { // nothing handled the disp mode printf('<div class="skin_error">Sub template [%s] not found.</div>', $template_name); if (!empty($current_User) && $current_User->level == 10) { printf('<div class="skin_error">User level 10 help info: [%s]</div>', $ads_current_skin_path . $template_name); } } $Timer->pause($timer_name); }
/** * Get the blog's media directory (and create it if necessary). * * If we're {@link is_admin_page() on an admin page}, it adds status messages. * @todo These status messages should rather go to a "syslog" and not be displayed to a normal user * @todo dh> refactor this into e.g. create_media_dir() and use it for Blog::get_media_dir, too. * * @param boolean Create the directory, if it does not exist yet? * @return string path string on success, false if the dir could not be created */ function get_media_dir($create = true) { global $media_path, $current_User, $Messages, $Settings, $Debuglog; if (!$Settings->get('fm_enable_roots_blog')) { // User directories are disabled: $Debuglog->add('Attempt to access blog media dir, but this feature is globally disabled', 'files'); return false; } switch ($this->media_location) { case 'default': $mediadir = get_canonical_path($media_path . 'blogs/' . $this->urlname . '/'); break; case 'subdir': $mediadir = get_canonical_path($media_path . $this->media_subdir); break; case 'custom': $mediadir = get_canonical_path($this->media_fullpath); break; case 'none': default: $Debuglog->add('Attempt to access blog media dir, but this feature is disabled for this blog', 'files'); return false; } // TODO: use a File object here (to access perms, ..), using FileCache::get_by_root_and_path(). if ($create && !is_dir($mediadir)) { // Display absolute path to blog admin and relative path to everyone else $msg_mediadir_path = $current_User->check_perm('blog_admin', 'edit', false, $this->ID) ? $mediadir : rel_path_to_base($mediadir); // TODO: Link to some help page(s) with errors! if (!is_writable(dirname($mediadir))) { // add error if (is_admin_page()) { $Messages->add(sprintf(T_("The blog's media directory «%s» could not be created, because the parent directory is not writable or does not exist."), $msg_mediadir_path) . get_manual_link('media_file_permission_errors'), 'error'); } return false; } elseif (!evo_mkdir($mediadir)) { // add error if (is_admin_page()) { $Messages->add(sprintf(T_("The blog's media directory «%s» could not be created."), $msg_mediadir_path) . get_manual_link('directory_creation_error'), 'error'); } return false; } else { // add note: if (is_admin_page()) { $Messages->add(sprintf(T_("The blog's media directory «%s» has been created with permissions %s."), $msg_mediadir_path, substr(sprintf('%o', fileperms($mediadir)), -3)), 'success'); } } } return $mediadir; }
/** * metaWeblog.newMediaObject image upload * * image is supplied coded in the info struct as bits * * @see http://www.xmlrpc.com/metaWeblogApi#metaweblognewmediaobject * * @todo do not overwrite existing pics with same name * @todo extensive permissions * * @param xmlrpcmsg XML-RPC Message * 0 blogid (string): Unique identifier of the blog the post will be added to. * Currently ignored in b2evo, in favor of the category. * 1 username (string): Login for a Blogger user who has permission to edit the given * post (either the user who originally created it or an admin of the blog). * 2 password (string): Password for said username. * 3 struct (struct) * - name : filename * - type : mimetype * - bits : base64 encoded file * @return xmlrpcresp XML-RPC Response */ function mw_newmediaobject($m) { global $xmlrpcerruser; // import user errcode value global $Settings, $baseurl, $fileupload_allowedtypes; // CHECK LOGIN: /** * @var User */ if (!($current_User =& xmlrpcs_login($m, 1, 2))) { // Login failed, return (last) error: return xmlrpcs_resperror(); } // GET BLOG: /** * @var Blog */ if (!($Blog =& xmlrpcs_get_Blog($m, 0))) { // Login failed, return (last) error: return xmlrpcs_resperror(); } // CHECK PERMISSION: // For lack of more subtle perm: require any edit perm on blog + global file add perm. if (!$current_User->check_perm('blog_post_statuses', 'edit', false, $Blog->ID) || !$current_User->check_perm('files', 'add', false)) { // Permission denied return xmlrpcs_resperror(3); // User error 3 } logIO('Permission granted.'); if (!$Settings->get('upload_enabled')) { return new xmlrpcresp(0, $xmlrpcerruser + 2, 'Object upload not allowed '); } $xcontent = $m->getParam(3); // Get the main data - and decode it properly for the image - sorry, binary object $contentstruct = xmlrpc_decode_recurse($xcontent); $data = $contentstruct['bits']; $type = $contentstruct['type']; logIO('Received MIME type: ' . $type); $rf_filepath = $contentstruct['name']; logIO('Received filepath: ' . $rf_filepath); // Avoid problems: $rf_filepath = strtolower($rf_filepath); $rf_filepath = preg_replace('¤[^a-z0-9\\-_./]¤', '-', $rf_filepath); logIO('Sanitized filepath: ' . $rf_filepath); load_funcs('files/model/_file.funcs.php'); // Split into path + name: $filepath_parts = explode('/', $rf_filepath); $filename = array_pop($filepath_parts); // Check valid filename/extension: (includes check for locked filenames) logIO('File name: ' . $filename); if ($error_filename = validate_filename($filename, false)) { return new xmlrpcresp(0, $xmlrpcerruser + 4, 'Invalid objecttype for upload (' . $filename . '): ' . $error_filename); } // Check valid path parts: $rds_subpath = ''; foreach ($filepath_parts as $filepath_part) { if (empty($filepath_part) || $filepath_part == '.') { // self ref not useful continue; } if ($error = validate_dirname($filepath_part)) { // invalid relative path: logIO($error); return new xmlrpcresp(0, $xmlrpcerruser + 3, $error); } $rds_subpath .= $filepath_part . '/'; } logIO('Subpath: ' . $rds_subpath); $fileupload_path = $Blog->get_media_dir(); if (!$fileupload_path) { return new xmlrpcresp(0, $xmlrpcerruser + 5, 'Error accessing Blog media directory.'); } // Create subdirs, if necessary: if (!empty($rds_subpath)) { $fileupload_path = $fileupload_path . $rds_subpath; if (!mkdir_r($fileupload_path)) { // Dir didn't already exist and could not be created return new xmlrpcresp(0, $xmlrpcerruser + 6, 'Error creating sub directories: ' . rel_path_to_base($fileupload_path)); } } $afs_filepath = $fileupload_path . $filename; logIO('Saving to: ' . $afs_filepath); $fh = @fopen($afs_filepath, 'wb'); if (!$fh) { logIO('Error opening file'); return new xmlrpcresp(0, $xmlrpcerruser + 7, 'Error opening file for writing.'); } $ok = @fwrite($fh, $data); @fclose($fh); if (!$ok) { logIO('Error writing to file'); return new xmlrpcresp(0, $xmlrpcerruser + 8, 'Error while writing to file.'); } // chmod uploaded file: $chmod = $Settings->get('fm_default_chmod_file'); logIO('chmod to: ' . $chmod); @chmod($afs_filepath, octdec($chmod)); $url = $Blog->get_media_url() . $rds_subpath . $filename; logIO('URL of new file: ' . $url); // - return URL as XML $urlstruct = new xmlrpcval(array('url' => new xmlrpcval($url, 'string')), 'struct'); logIO('OK.'); return new xmlrpcresp($urlstruct); }
/** * Get the path to the media directory. If it does not exist, it will be created. * * If we're {@link is_admin_page() on an admin page}, it adds status messages. * @todo These status messages should rather go to a "syslog" and not be displayed to a normal user * @todo dh> refactor this into e.g. create_media_dir() and use it for Blog::get_media_dir, too. * * @param boolean Create the directory, if it does not exist yet? * @return mixed the path as string on success, false if the dir could not be created */ function get_media_dir($create = true) { global $media_path, $Messages, $Settings, $Debuglog; if (!$Settings->get('fm_enable_roots_user')) { // User directories are disabled: $Debuglog->add('Attempt to access user media dir, but this feature is disabled', 'files'); return false; } $userdir = get_canonical_path($media_path . $this->get_media_subpath()); if ($create && !is_dir($userdir)) { if (!is_writable(dirname($userdir))) { // add error if (is_admin_page()) { $Messages->add(sprintf(T_("The user's media directory «%s» could not be created, because the parent directory is not writable or does not exist."), rel_path_to_base($userdir)) . get_manual_link('directory_creation_error'), 'error'); } return false; } elseif (!evo_mkdir($userdir)) { // add error if (is_admin_page()) { $Messages->add(sprintf(T_("The user's media directory «%s» could not be created."), rel_path_to_base($userdir)) . get_manual_link('directory_creation_error'), 'error'); } return false; } else { // add note: if (is_admin_page()) { $Messages->add(sprintf(T_("The user's directory «%s» has been created with permissions %s."), rel_path_to_base($userdir), substr(sprintf('%o', fileperms($userdir)), -3)), 'success'); } } } return $userdir; }
} if (empty($disp_handler)) { // Set $disp_handler only if it is not defined above: if (!empty($disp_handlers[$disp])) { if (file_exists($disp_handler = $ads_current_skin_path . $disp_handlers[$disp])) { // The current skin has a customized page handler for this disp: $Debuglog->add('blog_main: include ' . rel_path_to_base($disp_handler) . ' (custom to this skin)', 'skins'); } else { // Fallback to the default "index" handler from the current skin dir: $disp_handler = $ads_current_skin_path . 'index.main.php'; $Debuglog->add('blog_main: include ' . rel_path_to_base($disp_handler) . ' (default handler)', 'skins'); } } else { // Use the default handler from the skins dir: $disp_handler = $ads_current_skin_path . 'index.main.php'; $Debuglog->add('blog_main: include ' . rel_path_to_base($disp_handler) . ' (default index handler)', 'skins'); } } // CALL THE MAIN TEMPLATE NOW: require $disp_handler; } // Save collected cached data if needed: $PageCache->end_collect(); } $Timer->pause('PageCache'); $Timer->pause('SKIN DISPLAY'); // LOG with APM: $Timer->log_duration('SKIN DISPLAY'); // We probably don't want to return to the caller if we have displayed a skin... // That is useful if the caller implements a custom display but we still use skins for RSS/ Atom etc.. exit(0);
function chooseexportfile() { global $exportedfile, $import_mode, $dispatcher; // Go through directory: $this_dir = dir(IMPORT_SRC_DIR); $r = ''; while ($this_file = $this_dir->read()) { if (preg_match('/^.+\\.txt$/i', $this_file)) { $r .= '<option value="' . format_to_output($this_file, 'formvalue') . '"'; if ($exportedfile == $this_file) { $r .= ' selected="selected"'; } $r .= '>' . format_to_output($this_file, 'entityencoded') . '</option>'; } } if ($r) { ?> <form action="<?php echo $dispatcher; ?> " class="center"> <p>First, choose a file to import (.TXT files from the b2evolution base directory):</p> <select name="exportedfile" onChange="submit()"> <?php echo $r; ?> </select> <input type="hidden" name="import_mode" value="<?php echo $import_mode; ?> " /> <input type="hidden" name="ctrl" value="mtimport" /> <input type="submit" value="Next step..." class="search" /> </form> <?php } else { // no file found ?> <div class="error"> <p class="center">No .TXT file found. Nothing to import...</p> <p class="center">Please copy your Movable Type .TXT export file into <?php echo rel_path_to_base(IMPORT_SRC_DIR); ?> .</p> </div> <?php } }
$text_color = imagecolorallocate($im_handle, 255, 0, 0); $y = 0; foreach ($err_lines as $err_string) { imagestring($im_handle, 2, 2, $y, $err_string, $text_color); $y += $line_height; } header('Content-type: image/png'); header_nocache(); // Do NOT cache errors! People won't see they have fixed them!! imagepng($im_handle); } } else { // We want the regular file: // Headers to display the file directly in the browser if (!is_readable($File->get_full_path())) { debug_die(sprintf('File "%s" is not readable!', rel_path_to_base($File->get_full_path()))); } $Filetype =& $File->get_Filetype(); if (!empty($Filetype)) { header('Content-type: ' . $Filetype->mimetype); if ($Filetype->viewtype == 'download') { header('Content-disposition: attachment; filename="' . addcslashes($File->get_name(), '\\"') . '"'); // escape quotes and slashes, according to RFC } } $file_path = $File->get_full_path(); header('Content-Length: ' . filesize($file_path)); // The URL refers to this specific file, therefore we can tell the browser that // it does not expire anytime soon. // fp> I don't think mtime changes anything to the cacheability of the data // if( $mtime && $mtime == $File->get_lastmod_ts() ) // TODO: dh> use salt here?! fp>what for?
</div> <?php if (!is_admin_page() && isset($Blog) && $Session->get('display_includes_' . $Blog->ID)) { // Wrap the include with a visible div: echo '<div class="dev-blocks dev-blocks--include dev-blocks--belowtoolbar">'; echo '<div class="dev-blocks-name"><b>'; if (!empty($disp_handler_custom)) { // Custom template echo 'CUSTOM Main template: '; if (empty($disp_handler_custom_found)) { // Custom template in NOT found echo $disp_handler_custom . ' -> Fallback to:'; } else { // Custom template in found echo $disp_handler_custom . ' -> Found:'; } } else { // Default template echo 'Main template: '; } echo '</b> ' . rel_path_to_base($disp_handler) . '</div>'; echo '</div>'; } ?> <?php if (!$locale_from_get) { locale_restore_previous(); }
/** * Include email template from folder /skins_email/custom/ or /skins_email/ * * @param string Template name * @param array Params */ function emailskin_include($template_name, $params = array()) { global $emailskins_path, $is_admin_page, $rsc_url; /** * @var Log */ global $Debuglog; global $Timer; $timer_name = 'emailskin_include(' . $template_name . ')'; $Timer->resume($timer_name); $is_customized = false; // Try to include custom template firstly $template_path = $emailskins_path . 'custom/' . $template_name; if (file_exists($template_path)) { // Include custom template file if it exists $Debuglog->add('emailskin_include: ' . rel_path_to_base($template_path), 'skins'); require $template_path; // This template is customized, Don't include standard template $is_customized = true; } if (!$is_customized) { // Try to include standard template only if custom template doesn't exist $template_path = $emailskins_path . $template_name; if (file_exists($template_path)) { // Include standard template file if it exists $Debuglog->add('emailskin_include: ' . rel_path_to_base($template_path), 'skins'); require $template_path; } } $Timer->pause($timer_name); }
// Determine if we are creating or updating... global $action; $creating = is_create_action($action); $Form =& new Form(NULL, 'ftyp_checkchanges', 'post', 'compact'); $Form->global_icon(T_('Delete this filetype!'), 'delete', regenerate_url('action', 'action=delete')); $Form->global_icon(T_('Cancel editing!'), 'close', regenerate_url('action')); $Form->begin_form('fform', $creating ? T_('New file type') : T_('File type')); $Form->hidden_ctrl(); $Form->hidden('action', $creating ? 'create' : 'update'); if (!$creating) { $Form->hidden('ftyp_ID', $edited_Filetype->ID); } $Form->text_input('ftyp_extensions', $edited_Filetype->extensions, 40, T_('Extensions'), '', array('maxlength' => 80, 'required' => true, 'note' => sprintf('E.g. «%s»' . ', ' . T_('separated by whitespace'), 'html'))); $Form->text_input('ftyp_name', $edited_Filetype->name, 40, T_('File type name'), sprintf('E.g. «%s»', 'HTML file'), array('maxlength' => 80, 'required' => true)); $Form->text_input('ftyp_mimetype', $edited_Filetype->mimetype, 40, T_('Mime type'), sprintf('E.g. «%s»', 'text/html'), array('maxlength' => 80, 'required' => true)); $Form->text('ftyp_icon', $edited_Filetype->icon, 20, T_('Icon'), sprintf(T_('File name of the icon, must be in %s.'), rel_path_to_base($rsc_path . 'icons/fileicons/')), 40); $Form->radio('ftyp_viewtype', $edited_Filetype->viewtype, array(array('browser', T_('Open with browser (popup)'), T_('Let the browser handle the file in a popup.')), array('text', T_('Open with text viewer (popup)'), T_('Use the online text viewer (recommended for .txt)')), array('image', T_('Open with image viewer (popup)'), T_('Use the online image viewer (recommended for .gif .png .jpg)')), array('external', T_('Open with external app (no popup)'), T_('Let the browser handle the file in a popup. Note: if you do not want Word to open inside of IE, you must uncheck "browse in same window" in Windows\' file types.')), array('download', T_('Download to disk (no popup)'), T_('Tell the browser to save the file to disk instead of displaying it.'))), T_('View type'), true); // Check if the extension is in the array of the not allowed upload extensions from _advanced.php $not_allowed = false; $extensions = explode(' ', $edited_Filetype->extensions); foreach ($extensions as $extension) { if (in_array($extension, $force_upload_forbiddenext)) { $not_allowed = true; continue; } } $Form->checkbox('ftyp_allowed', $edited_Filetype->allowed, T_('Allow upload'), T_('Check to allow uploading and renaming of this file type'), '', 1, $not_allowed); if ($creating) { $Form->end_form(array(array('submit', 'submit', T_('Record'), 'SaveButton'), array('submit', 'submit', T_('Record, then Create New'), 'SaveButton'), array('submit', 'submit', T_('Record, then Create Similar'), 'SaveButton'), array('reset', '', T_('Reset'), 'ResetButton'))); } else { $Form->end_form(array(array('submit', 'submit', T_('Update'), 'SaveButton'), array('reset', '', T_('Reset'), 'ResetButton')));
/** * Template tag. * * @param string Template name * @param array Params * @param boolean force include even if sitewide header/footer not enabled */ function siteskin_include($template_name, $params = array(), $force = false) { global $Settings, $siteskins_path, $Blog; if (!$Settings->get('site_skins_enabled') && !$force) { // Site skins are not enabled and we don't want to force either return; } if (is_ajax_content($template_name)) { // When we request ajax content for results table we need to hide wrapper data (header, footer & etc) return; } // Globals that may be needed by the template: global $current_User, $Hit, $Session, $Settings; global $skin_url, $htsrv_url, $htsrv_url_sensitive; global $samedomain_htsrv_url, $secure_htsrv_url; global $credit_links, $skin_links, $francois_links, $fplanque_links, $skinfaktory_links; /** * @var Log */ global $Debuglog; global $Timer; $timer_name = 'siteskin_include(' . $template_name . ')'; $Timer->resume($timer_name); if (file_exists($siteskins_path . 'custom/' . $template_name)) { // Use the custom template: $file = $siteskins_path . 'custom/' . $template_name; $debug_info = '<b>Custom template</b>: ' . rel_path_to_base($file); $disp_handled = 'custom'; } elseif (file_exists($siteskins_path . $template_name)) { // Use the default/fallback template: $file = $siteskins_path . $template_name; $debug_info = '<b>Fallback to</b>: ' . rel_path_to_base($file); $disp_handled = 'fallback'; } else { $disp_handled = false; } // Do we want a visible container for DEBUG/DEV ?: if (strpos($template_name, '_html_') !== false || strpos($template_name, '_init.') !== false) { // We're outside of the page body: NEVER display wrap this include with a <div> $display_includes = false; } elseif (isset($Session)) { // We may wrap with a <div>: $display_includes = $Session->get('display_includes_' . (empty($Blog) ? 0 : $Blog->ID)) == 1; } else { // Request without defined $Session, Don't display the includes: $display_includes = false; } if ($display_includes) { // Wrap the include with a visible div: echo '<div class="dev-blocks dev-blocks--siteinclude">'; echo '<div class="dev-blocks-name">siteskin_include( <b>' . $template_name . '</b> ) -> ' . $debug_info . '</div>'; } if ($disp_handled) { $Debuglog->add('siteskin_include: ' . rel_path_to_base($file), 'skins'); require $file; } else { // nothing handled the display printf('<div class="skin_error">Site template [%s] not found.</div>', $template_name); if (!empty($current_User) && $current_User->level == 10) { printf('<div class="skin_error">User level 10 help info: [%s]</div>', $siteskins_path . $template_name); } } if ($display_includes) { // End of visible container: // echo get_icon( 'pixel', 'imgtag', array( 'class' => 'clear' ) ); echo '</div>'; } $Timer->pause($timer_name); }
$Messages->add('Sorry, you cannot update files in demo mode!', 'error'); break; } // Check permission! $current_User->check_perm('files', 'edit_allowed', true, $selected_Filelist->get_FileRoot()); // Get the file we want to update: $edited_File =& $selected_Filelist->get_by_idx(0); // Check that the file is editable: if (!$edited_File->is_editable($current_User->check_perm('files', 'all'))) { $Messages->add(sprintf(T_('You are not allowed to edit «%s».'), $edited_File->dget('name')), 'error'); break; } param('file_content', 'html', '', false); $fpath = $edited_File->get_full_path(); if (file_exists($fpath) && !is_writeable($fpath)) { $Messages->add(sprintf('The file «%s» is not writable.', rel_path_to_base($fpath)), 'error'); break; } if (save_to_file($file_content, $fpath, 'w+')) { $Messages->add(sprintf(T_('The file «%s» has been updated.'), $edited_File->dget('name')), 'success'); } else { $Messages->add(sprintf(T_('The file «%s» could not be updated.'), $edited_File->dget('name')), 'error'); } header_redirect(regenerate_url('', '', '', '&')); // $action = 'list'; break; } // Do we want to display the directory tree next to the files table $UserSettings->param_Request('fm_hide_dirtree', 'fm_hide_dirtree', 'integer', 0, true); /** * Filelist