public function do_execute() { $variables = array(); // Handle updating of theme options. if (isset($_POST[Ai1ec_View_Theme_Options::SUBMIT_ID])) { $_POST = stripslashes_deep($_POST); $lessphp = $this->_registry->get('less.lessphp'); $variables = $lessphp->get_saved_variables(); foreach ($variables as $variable_name => $variable_params) { if (isset($_POST[$variable_name])) { // Avoid problems for those who are foolish enough to leave php.ini // settings at their defaults, which has magic quotes enabled. if (get_magic_quotes_gpc()) { $_POST[$variable_name] = stripslashes($_POST[$variable_name]); } if (Ai1ec_Less_Variable_Font::CUSTOM_FONT === $_POST[$variable_name]) { $_POST[$variable_name] = $_POST[$variable_name . Ai1ec_Less_Variable_Font::CUSTOM_FONT_ID_SUFFIX]; } // update the original array $variables[$variable_name]['value'] = $_POST[$variable_name]; } } $_POST = add_magic_quotes($_POST); } elseif (isset($_POST[Ai1ec_View_Theme_Options::RESET_ID])) { $option = $this->_registry->get('model.option'); $option->delete('ai1ec_less_variables'); $option->delete('ai1ec_render_css'); do_action('ai1ec_reset_less_variables'); } $css = $this->_registry->get('css.frontend'); $css->update_variables_and_compile_css($variables, isset($_POST[Ai1ec_View_Theme_Options::RESET_ID])); return array('url' => ai1ec_admin_url('edit.php?post_type=ai1ec_event&page=all-in-one-event-calendar-edit-css'), 'query_args' => array()); }
/** * Runs checks for necessary config options. * * @return void Method does not return. */ public function run_checks() { $role = get_role('administrator'); $current_user = get_userdata(get_current_user_id()); if (!is_object($role) || !is_object($current_user) || !$role->has_cap('manage_ai1ec_options') || defined('DOING_AJAX') && DOING_AJAX) { return; } do_action('ai1ec_env_check'); global $plugin_page; $settings = $this->_registry->get('model.settings'); $option = $this->_registry->get('model.option'); $notification = $this->_registry->get('notification.admin'); $created_calendar_page = false; // check if is set calendar page if (!$settings->get('calendar_page_id')) { $calendar_page_id = wp_insert_post(array('post_title' => 'Calendar', 'post_type' => 'page', 'post_status' => 'publish', 'comment_status' => 'closed')); $settings->set('calendar_page_id', $calendar_page_id); $created_calendar_page = true; } if ($plugin_page !== AI1EC_PLUGIN_NAME . '-settings' && $created_calendar_page) { if ($current_user->has_cap('manage_ai1ec_options')) { $msg = sprintf(Ai1ec_I18n::__('The plugin is successfully installed! <a href="%s">Add some events</a> and see them on your <a href="%s">Calendar page</a>.<br />Visit the <a href="%s">Settings page</a> to configure the plugin and get most of it.'), 'post-new.php?post_type=ai1ec_event', get_page_link($calendar_page_id), ai1ec_admin_url(AI1EC_SETTINGS_BASE_URL)); $notification->store($msg, 'updated', 2, array(Ai1ec_Notification_Admin::RCPT_ADMIN)); } else { $msg = Ai1ec_I18n::__('The plugin is installed, but has not been configured. Please log in as an Administrator to set it up.'); $notification->store($msg, 'updated', 2, array(Ai1ec_Notification_Admin::RCPT_ALL)); } return; } // Tell user to sign in to API in order to use Feeds $ics_current_db_version = $option->get(Ai1ecIcsConnectorPlugin::ICS_OPTION_DB_VERSION); if ($ics_current_db_version != null && $ics_current_db_version != '') { $rows = $this->_registry->get('dbi.dbi')->select('ai1ec_event_feeds', array('feed_id')); $api_reg = $this->_registry->get('model.api.api-registration'); $is_signed = $api_reg->is_signed(); if (0 < count($rows) && !$is_signed) { $msg = Ai1ec_I18n::__('<b>ACTION REQUIRED!</b> Please, <a href="edit.php?post_type=ai1ec_event&page=all-in-one-event-calendar-settings">sign</a> into Timely Network to continue syncing your imported events.'); $notification->store($msg, 'error', 0, array(Ai1ec_Notification_Admin::RCPT_ADMIN), false); } } // Check for needed PHP extensions. if (!function_exists('iconv') && !$option->get('ai1ec_iconv_notification')) { $msg = Ai1ec_I18n::__('PHP extension "iconv" needed for All-In-One-Event-Calendar is missing. Please, check your PHP configuration.<br />'); $notification->store($msg, 'error', 0, array(Ai1ec_Notification_Admin::RCPT_ADMIN), true); $option->set('ai1ec_iconv_notification', true); } if (!function_exists('mb_check_encoding') && !$option->get('ai1ec_mbstring_notification')) { $msg = Ai1ec_I18n::__('PHP extension "mbstring" needed for All-In-One-Event-Calendar is missing. Please, check your PHP configuration.<br />'); $notification->store($msg, 'error', 0, array(Ai1ec_Notification_Admin::RCPT_ADMIN), true); $option->set('ai1ec_mbstring_notification', true); } global $wp_rewrite; $option = $this->_registry->get('model.option'); $rewrite = $option->get('ai1ec_force_flush_rewrite_rules'); if (!$rewrite || !is_object($wp_rewrite) || !isset($wp_rewrite->rules) || 0 === count($wp_rewrite->rules)) { return; } $this->_registry->get('rewrite.helper')->flush_rewrite_rules(); $option->set('ai1ec_force_flush_rewrite_rules', false); }
/** * Executes the command to change the active theme. * * NOTE: {@see self::is_this_to_execute} must return true for this command * to execute; we can trust that input has been checked for injections. */ public function do_execute() { // Update the active theme in the options table. $stylesheet = preg_replace('|[^a-z_\\-]+|i', '', $_GET['ai1ec_stylesheet']); $this->_registry->get('theme.loader')->switch_theme(array('theme_root' => realpath($_GET['ai1ec_theme_root']), 'theme_dir' => realpath($_GET['ai1ec_theme_dir']), 'theme_url' => $_GET['ai1ec_theme_url'], 'stylesheet' => $stylesheet, 'legacy' => false)); // Return user to themes list page with success message. return array('url' => ai1ec_admin_url('edit.php?post_type=ai1ec_event&page=all-in-one-event-calendar-themes'), 'query_args' => array('activated' => 1)); }
/** * Display the page html */ public function display_page() { $settings = $this->_registry->get('model.settings'); $args = array('title' => Ai1ec_I18n::__('Time.ly Ticketing beta'), 'nonce' => array('action' => self::NONCE_ACTION, 'name' => self::NONCE_NAME, 'referrer' => false), 'metabox' => array('screen' => $settings->get('enabling_ticket_invitation_page'), 'action' => 'left', 'object' => null), 'action' => ai1ec_admin_url('?controller=front&action=ai1ec_ticketing_invitation_save&plugin=' . AI1EC_PLUGIN_NAME)); $loader = $this->_registry->get('theme.loader'); $file = $loader->get_file('ticketing-invitation/page.twig', $args, true); $this->_registry->get('css.admin')->admin_enqueue_scripts('ai1ec_event_page_all-in-one-event-calendar-settings'); $this->_registry->get('css.admin')->process_enqueue(array(array('style', 'ticketing.css'))); return $file->render(); }
/** * Adds a link to Settings page in plugin list page. * * @param array $links List of available links. * * @return array Modified links list. */ public function plugin_action_links($links) { $settings_link = sprintf(Ai1ec_I18n::__('<a href="%s">Settings</a>'), ai1ec_admin_url(AI1EC_SETTINGS_BASE_URL)); array_unshift($links, $settings_link); if (current_user_can('activate_plugins')) { $updates_link = sprintf(Ai1ec_I18n::__('<a href="%s">Check for updates</a>'), ai1ec_admin_url(AI1EC_FORCE_UPDATES_URL)); array_push($links, $updates_link); } return $links; }
/** * Returns the translations array * * @return array */ private function get_translations() { $categories = isset($_POST['ai1ec_categories']) ? $_POST['ai1ec_categories'] : array(); foreach ($categories as &$cat) { $term = get_term($cat, 'events_categories'); $cat = $term->name; } $translations = array('[feed_url]' => $_POST['ai1ec_calendar_url'], '[categories]' => implode(', ', $categories), '[user_email]' => $_POST['ai1ec_submitter_email'], '[site_title]' => get_bloginfo('name'), '[site_url]' => ai1ec_site_url(), '[feeds_url]' => ai1ec_admin_url(AI1EC_FEED_SETTINGS_BASE_URL . '#ics')); return $translations; }
public function do_execute() { $api_settings = $this->_registry->get('helper.api-settings'); if (isset($_POST['ai1ec_ticketing']) && $_POST['ai1ec_ticketing'] == '1') { $api_settings->ai1ec_setting_up_api_flags(true); } else { $api_settings->ai1ec_setting_up_api_flags(false); } return array('url' => ai1ec_admin_url('edit.php?post_type=ai1ec_event&page=all-in-one-event-calendar-invitation'), 'query_args' => array('updated' => 1)); }
public function display_page() { $settings = $this->_registry->get('model.settings'); $args = array('title' => Ai1ec_I18n::__('All-in-One Event Calendar: Settings'), 'nonce' => array('action' => self::NONCE_ACTION, 'name' => self::NONCE_NAME, 'referrer' => false), 'metabox' => array('screen' => $settings->get('settings_page'), 'action' => 'left', 'object' => null), 'support' => array('screen' => $settings->get('settings_page'), 'action' => 'right', 'object' => null), 'action' => ai1ec_admin_url('?controller=front&action=ai1ec_save_settings&plugin=' . AI1EC_PLUGIN_NAME)); $loader = $this->_registry->get('theme.loader'); $file = $loader->get_file('setting/page.twig', $args, true); $file->render(); if (apply_filters('ai1ec_robots_install', true)) { $this->_registry->get('robots.helper')->install(); } }
/** * Renders the html of the page and returns it. * * @param Ai1ec_Event $event * * @return string the html of the page */ public function get_content(Ai1ec_Event $event) { $settings = $this->_registry->get('model.settings'); $rrule = $this->_registry->get('recurrence.rule'); $taxonomy = $this->_registry->get('view.event.taxonomy'); $location = $this->_registry->get('view.event.location'); $ticket = $this->_registry->get('view.event.ticket'); $content = $this->_registry->get('view.event.content'); $time = $this->_registry->get('view.event.time'); $subscribe_url = AI1EC_EXPORT_URL . '&ai1ec_post_ids=' . $event->get('post_id'); $event->set_runtime('tickets_url_label', $ticket->get_tickets_url_label($event, false)); $event->set_runtime('content_img_url', $content->get_content_img_url($event)); $extra_buttons = apply_filters('ai1ec_rendering_single_event_actions', '', $event); $venues_html = apply_filters('ai1ec_rendering_single_event_venues', nl2br($location->get_location($event)), $event); $timezone_info = array('show_timezone' => false, 'text_timezone_title' => null, 'event_timezone' => null); $default_tz = $this->_registry->get('date.timezone')->get_default_timezone(); /** * Only display the timezone information if: * -) local timezone is not enforced -- because if it is enforced * then site owner knows that it's clear, from event contents, * where event happens and what time means; * -) the timezone is different from the site timezone because if * they do match then it is likely obvious when and wheere the * event is about to take place. */ if ($this->_registry->get('model.settings')->get('always_use_calendar_timezone') && $event->get('timezone_name') !== $default_tz) { $timezone_info = array('show_timezone' => true, 'event_timezone' => $event->get('timezone_name'), 'text_timezone_title' => sprintf(Ai1ec_I18n::__('Event was created in the %s time zone'), $event->get('start')->get_gmt_offset_as_text())); } $banner_image_meta = get_post_meta($event->get('post_id'), 'ai1ec_banner_image'); $banner_image = $banner_image_meta ? $banner_image_meta[0] : ''; // objects are passed by reference so an action is ok do_action('ai1ec_single_event_page_before_render', $event); $filter_groups_html = apply_filters('ai1ec_get_filter_groups_html', $event); $args = array('event' => $event, 'recurrence' => $rrule->rrule_to_text($event->get('recurrence_rules')), 'exclude' => $time->get_exclude_html($event, $rrule), 'categories' => $taxonomy->get_categories_html($event), 'tags' => $taxonomy->get_tags_html($event), 'location' => html_entity_decode($venues_html), 'filter_groups' => $filter_groups_html, 'map' => $location->get_map_view($event), 'contact' => $ticket->get_contact_html($event), 'back_to_calendar' => $content->get_back_to_calendar_button_html(), 'subscribe_url' => $subscribe_url, 'subscribe_url_no_html' => $subscribe_url . '&no_html=true', 'edit_instance_url' => null, 'edit_instance_text' => null, 'google_url' => 'http://www.google.com/calendar/render?cid=' . urlencode($subscribe_url), 'show_subscribe_buttons' => !$settings->get('turn_off_subscription_buttons'), 'hide_featured_image' => $settings->get('hide_featured_image'), 'extra_buttons' => $extra_buttons, 'show_get_calendar' => !$settings->get('disable_get_calendar_button'), 'text_add_calendar' => __('Add to Calendar', AI1EC_PLUGIN_NAME), 'subscribe_buttons_text' => $this->_registry->get('view.calendar.subscribe-button')->get_labels(), 'text_get_calendar' => Ai1ec_I18n::__('Get a Timely Calendar'), 'text_when' => __('When:', AI1EC_PLUGIN_NAME), 'text_where' => __('Where:', AI1EC_PLUGIN_NAME), 'text_cost' => __('Cost:', AI1EC_PLUGIN_NAME), 'text_contact' => __('Contact:', AI1EC_PLUGIN_NAME), 'text_tickets' => __('Tickets:', AI1EC_PLUGIN_NAME), 'text_free' => __('Free', AI1EC_PLUGIN_NAME), 'text_categories' => __('Categories', AI1EC_PLUGIN_NAME), 'text_tags' => __('Tags', AI1EC_PLUGIN_NAME), 'buy_tickets_text' => __('Buy Tickets', AI1EC_PLUGIN_NAME), 'timezone_info' => $timezone_info, 'banner_image' => $banner_image, 'content_img_url' => $event->get_runtime('content_img_url'), 'post_id' => $event->get('post_id'), 'ticket_url' => $event->get('ticket_url'), 'tickets_url_label' => $event->get_runtime('tickets_url_label'), 'start' => $event->get('start'), 'end' => $event->get('end'), 'cost' => $event->get('cost'), 'instance_id' => $event->get('instance_id')); if (!empty($args['recurrence']) && $event->get('instance_id') && current_user_can('edit_ai1ec_events')) { $args['edit_instance_url'] = ai1ec_admin_url('post.php?post=' . $event->get('post_id') . '&action=edit&instance=' . $event->get('instance_id')); $args['edit_instance_text'] = sprintf(Ai1ec_I18n::__('Edit this occurrence (%s)'), $event->get('start')->format_i18n('M j')); } $loader = $this->_registry->get('theme.loader'); $api = $this->_registry->get('model.api.api-ticketing'); if (false === ai1ec_is_blank($event->get('ical_feed_url'))) { $args['ticket_url'] = $api->get_api_event_buy_ticket_url($event->get('post_id')); } else { $api_event_id = $api->get_api_event_id($event->get('post_id')); if ($api_event_id) { $api = $this->_registry->get('model.api.api-ticketing'); $ticket_types = json_decode($api->get_ticket_types($event->get('post_id'), false)); $args['has_tickets'] = true; $args['API_URL'] = AI1EC_API_URL; $args['tickets_block'] = $loader->get_file('tickets.twig', array('tickets_checkout_url' => $api->get_api_event_buy_ticket_url($event->get('post_id')), 'tickets' => $ticket_types->data, 'text_tickets' => $args['text_tickets'], 'buy_tickets_text' => $args['buy_tickets_text'], 'api_event_id' => $api_event_id), false)->get_content(); } } return $loader->get_file('event-single.twig', $args, false)->get_content(); }
public function do_execute() { $api = $this->_registry->get('model.api.api-registration'); if (true === isset($_POST['ai1ec_signout']) && '1' === $_POST['ai1ec_signout']) { $api->signout(); } else { if ('1' === $_POST['ai1ec_signing']) { $api->signup(); } else { $api->signin(); } } return array('url' => ai1ec_admin_url('edit.php?post_type=ai1ec_event&page=all-in-one-event-calendar-settings'), 'query_args' => array('message' => '')); }
/** * Runs checks for necessary config options. * * @return void Method does not return. */ public function run_checks() { $role = get_role('administrator'); $current_user = get_userdata(get_current_user_id()); if (!is_object($role) || !is_object($current_user) || !$role->has_cap('manage_ai1ec_options') || defined('DOING_AJAX') && DOING_AJAX) { return; } do_action('ai1ec_env_check'); global $plugin_page; $settings = $this->_registry->get('model.settings'); $notification = $this->_registry->get('notification.admin'); $created_calendar_page = false; // check if is set calendar page if (!$settings->get('calendar_page_id')) { $calendar_page_id = wp_insert_post(array('post_title' => 'Calendar', 'post_type' => 'page', 'post_status' => 'publish', 'comment_status' => 'closed')); $settings->set('calendar_page_id', $calendar_page_id); $created_calendar_page = true; } if ($plugin_page !== AI1EC_PLUGIN_NAME . '-settings' && $created_calendar_page) { if ($current_user->has_cap('manage_ai1ec_options')) { $msg = sprintf(Ai1ec_I18n::__('The plugin is successfully installed! <a href="%s">Add some events</a> and see them on your <a href="%s">Calendar page</a>.<br />Visit the <a href="%s">Settings page</a> to configure the plugin and get most of it.'), 'post-new.php?post_type=ai1ec_event', get_page_link($calendar_page_id), ai1ec_admin_url(AI1EC_SETTINGS_BASE_URL)); $notification->store($msg, 'updated', 2, array(Ai1ec_Notification_Admin::RCPT_ADMIN)); } else { $msg = Ai1ec_I18n::__('The plugin is installed, but has not been configured. Please log in as an Administrator to set it up.'); $notification->store($msg, 'updated', 2, array(Ai1ec_Notification_Admin::RCPT_ALL)); } return; } // Check for needed PHP extensions. $option = $this->_registry->get('model.option'); if (!function_exists('iconv') && !$option->get('ai1ec_iconv_notification')) { $msg = Ai1ec_I18n::__('PHP extension "iconv" needed for All-In-One-Event-Calendar is missing. Please, check your PHP configuration.<br />'); $notification->store($msg, 'error', 0, array(Ai1ec_Notification_Admin::RCPT_ADMIN), true); $option->set('ai1ec_iconv_notification', true); } if (!function_exists('mb_check_encoding') && !$option->get('ai1ec_mbstring_notification')) { $msg = Ai1ec_I18n::__('PHP extension "mbstring" needed for All-In-One-Event-Calendar is missing. Please, check your PHP configuration.<br />'); $notification->store($msg, 'error', 0, array(Ai1ec_Notification_Admin::RCPT_ADMIN), true); $option->set('ai1ec_mbstring_notification', true); } global $wp_rewrite; $option = $this->_registry->get('model.option'); $rewrite = $option->get('ai1ec_force_flush_rewrite_rules'); if (!$rewrite || !is_object($wp_rewrite) || !isset($wp_rewrite->rules) || 0 === count($wp_rewrite->rules)) { return; } $this->_registry->get('rewrite.helper')->flush_rewrite_rules(); $option->set('ai1ec_force_flush_rewrite_rules', false); }
/** * Retrieve duplicate post link for post. * * * @param int $id Optional. Post ID. * @param string $context Optional, default to display. How to write the '&', defaults to '&'. * @param string $draft Optional, default to true * @return string */ function ai1ec_duplicate_post_get_clone_post_link($id = 0, $context = 'display', $draft = true) { if (!($post = get_post($id))) { return; } if ($draft) { $action_name = "ai1ec_duplicate_post_save_as_new_post_draft"; } else { $action_name = "ai1ec_duplicate_post_save_as_new_post"; } if ('display' == $context) { $action = '?action=' . $action_name . '&post=' . $post->ID; } else { $action = '?action=' . $action_name . '&post=' . $post->ID; } $post_type_object = get_post_type_object($post->post_type); if (!$post_type_object) { return; } return apply_filters('ai1ec_duplicate_post_get_clone_post_link', wp_nonce_url(ai1ec_admin_url('admin.php' . $action), 'ai1ec_clone_' . $post->ID), $post->ID, $context); }
/** * Runs checks for necessary config options. * * @return void Method does not return. */ public function run_checks() { $role = get_role('administrator'); $current_user = get_userdata(get_current_user_id()); if (!is_object($role) || !is_object($current_user) || !$role->has_cap('manage_ai1ec_options') || defined('DOING_AJAX') && DOING_AJAX) { return; } do_action('ai1ec_env_check'); global $plugin_page; $settings = $this->_registry->get('model.settings'); $notification = $this->_registry->get('notification.admin'); $notifications = array(); // check if is set calendar page if (!$settings->get('calendar_page_id')) { $msg = Ai1ec_I18n::__('Select an option in the <strong>Calendar page</strong> dropdown list.'); $notifications[] = $msg; } if ($plugin_page !== AI1EC_PLUGIN_NAME . '-settings' && !empty($notifications)) { if ($current_user->has_cap('manage_ai1ec_options')) { $msg = sprintf(Ai1ec_I18n::__('The plugin is installed, but has not been configured. <a href="%s">Click here to set it up now »</a>'), ai1ec_admin_url(AI1EC_SETTINGS_BASE_URL)); $notification->store($msg, 'updated', 2, array(Ai1ec_Notification_Admin::RCPT_ADMIN)); } else { $msg = Ai1ec_I18n::__('The plugin is installed, but has not been configured. Please log in as an Administrator to set it up.'); $notification->store($msg, 'updated', 2, array(Ai1ec_Notification_Admin::RCPT_ALL)); } return; } foreach ($notifications as $msg) { $notification->store($msg, 'updated', 2, array(Ai1ec_Notification_Admin::RCPT_ADMIN)); } global $wp_rewrite; $option = $this->_registry->get('model.option'); $rewrite = $option->get('ai1ec_force_flush_rewrite_rules'); if (!$rewrite || !is_object($wp_rewrite) || !isset($wp_rewrite->rules) || 0 === count($wp_rewrite->rules)) { return; } $this->_registry->get('rewrite.helper')->flush_rewrite_rules(); $option->set('ai1ec_force_flush_rewrite_rules', false); }
public function do_execute() { $settings = $this->_registry->get('model.settings'); $options = $settings->get_options(); $_POST['default_tags_categories'] = isset($_POST['default_tags_categories_default_categories']) || isset($_POST['default_tags_categories_default_tags']); // set some a variable to true to trigger the saving. $_POST['enabled_views'] = true; // let other plugin modify the post $_POST = apply_filters('ai1ec_before_save_settings', $_POST); foreach ($options as $name => $data) { $value = null; if (isset($_POST[$name])) { // if a validator is pecified, use it. if (isset($data['renderer']['validator'])) { $validator = $this->_registry->get('validator.' . $data['renderer']['validator'], $_POST[$name]); try { $value = $validator->validate(); } catch (Ai1ec_Value_Not_Valid_Exception $e) { // don't save continue; } } else { switch ($data['type']) { case 'bool': $value = true; break; case 'int': $value = (int) $_POST[$name]; break; case 'string': $value = (string) $_POST[$name]; break; case 'array': $method = '_handle_saving_' . $name; $value = null; if (method_exists($this, $method)) { $value = $this->{$method}(); } $value = apply_filters('ai1ec' . $method, $value, $_REQUEST); break; case 'mixed': $method = '_handle_saving_' . $name; $value = null; if (method_exists($this, $method)) { $value = $this->{$method}($_POST[$name]); } $value = apply_filters('ai1ec' . $method, $value, $_REQUEST); break; case 'wp_option': // set the corresponding WP option $this->_registry->get('model.option')->set($name, $_POST[$name], true); $value = (string) $_POST[$name]; } } } else { if (isset($data['type']) && 'bool' === $data['type']) { $value = false; } } if (null !== $value) { $settings->set($name, stripslashes_deep($value)); } } $new_options = $settings->get_options(); // let extension manipulate things if needed. do_action('ai1ec_settings_updated', $options, $new_options); $settings->persist(); return array('url' => ai1ec_admin_url('edit.php?post_type=ai1ec_event&page=all-in-one-event-calendar-settings'), 'query_args' => array('updated' => 1)); }
public function do_execute() { $this->_registry->get('calendar.updates')->clear_transients(); return array('url' => ai1ec_admin_url('plugins.php'), 'query_args' => array()); }
/** * Install robotx.txt into current Wordpress instance * * @return void */ public function install() { $option = $this->_registry->get('model.option'); $settings = $this->_registry->get('model.settings'); $robots = $option->get('ai1ec_robots_txt'); if (isset($robots['page_id']) && $robots['page_id'] == $settings->get('calendar_page_id')) { return; } $ftp_base_dir = defined('FTP_BASE') ? FTP_BASE . DIRECTORY_SEPARATOR : ''; // we can't use ABSPATH for ftp, if ftp user is not chrooted they need // to define FTP_BASE in wp-config.php $robots_file = $ftp_base_dir . 'robots.txt'; $robots_txt = array(); $is_installed = false; $current_rules = null; $custom_rules = $this->rules('', false); $url = wp_nonce_url('edit.php?post_type=ai1ec_event&page=all-in-one-event-calendar-settings', 'ai1ec-nonce'); $redirect_url = ai1ec_admin_url('edit.php?post_type=ai1ec_event&page=all-in-one-event-calendar-settings&noredirect=1'); if (!function_exists('request_filesystem_credentials')) { return; } $type = get_filesystem_method(); if ('direct' === $type) { // we have to use ABSPATH for direct $robots_file = ABSPATH . 'robots.txt'; } $creds = request_filesystem_credentials($url, $type, false, false, null); if (!WP_Filesystem($creds)) { $error_v = isset($_POST['hostname']) || isset($_POST['username']) || isset($_POST['password']) || isset($_POST['connection_type']); if ($error_v) { // if credentials are given and we don't have access to // wp filesystem show notice to user // we could use request_filesystem_credentials with true error // parameter but in this case second ftp credentials screen // would appear $notification = $this->_registry->get('notification.admin'); $err_msg = Ai1ec_I18n::__('<strong>ERROR:</strong> There was an error connecting to the server, Please verify the settings are correct.'); $notification->store($err_msg, 'error', 1); // we need to avoid infinity loop if FS_METHOD direct // and robots.txt is not writable if (!isset($_REQUEST['noredirect'])) { Ai1ec_Http_Response_Helper::redirect($redirect_url); } } return; } global $wp_filesystem; // sometimes $wp_filesystem could be null if (null === $wp_filesystem) { return; } $redirect = false; if ($wp_filesystem->exists($robots_file) && $wp_filesystem->is_readable($robots_file) && $wp_filesystem->is_writable($robots_file)) { // Get current robots txt content $current_rules = $wp_filesystem->get_contents($robots_file); // Update robots.txt $custom_rules = $this->rules($current_rules, false); } $robots_txt['is_installed'] = $wp_filesystem->put_contents($robots_file, $custom_rules, FS_CHMOD_FILE); if (false === $robots_txt['is_installed']) { $err_msg = Ai1ec_I18n::__('<strong>ERROR:</strong> There was an error storing <strong>robots.txt</strong> to the server, the file could not be written.'); $this->_registry->get('notification.admin')->store($err_msg, 'error'); $redirect = true; } // Set Page ID $robots_txt['page_id'] = $settings->get('calendar_page_id'); // Update Robots Txt $option->set('ai1ec_robots_txt', $robots_txt); // Update settings textarea $settings->set('edit_robots_txt', $custom_rules); // we need to avoid infinity loop if FS_METHOD direct // and robots.txt is not writable if ($redirect && !isset($_REQUEST['noredirect'])) { Ai1ec_Http_Response_Helper::redirect($redirect_url); } }
/** * Create the array needed for translation and passing other settings to JS. * * @return $data array the dynamic data array */ public function get_translation_data() { $force_ssl_admin = force_ssl_admin(); if ($force_ssl_admin && !is_ssl()) { force_ssl_admin(false); } $ajax_url = ai1ec_admin_url('admin-ajax.php'); force_ssl_admin($force_ssl_admin); $settings = $this->_registry->get('model.settings'); $locale = $this->_registry->get('p28n.wpml'); $blog_timezone = $this->_registry->get('model.option')->get('gmt_offset'); $application = $this->_registry->get('bootstrap.registry.application'); $data = array('calendar_feeds_nonce' => wp_create_nonce('ai1ec_ics_feed_nonce'), 'duplicate_feed_message' => esc_html(Ai1ec_I18n::__('This feed is already being imported.')), 'invalid_url_message' => esc_html(Ai1ec_I18n::__('Please enter a valid iCalendar URL.')), 'invalid_email_message' => esc_html(Ai1ec_I18n::__('Please enter a valid email address.')), 'choose_image_message' => Ai1ec_I18n::__('Choose Image'), 'now' => $this->_registry->get('date.system')->current_time(), 'size_less_variable_not_ok' => Ai1ec_I18n::__('The value you have entered is not a valid CSS length.'), 'confirm_reset_theme' => Ai1ec_I18n::__('Are you sure you want to reset your theme options to their default values?'), 'error_message_not_valid_lat' => Ai1ec_I18n::__('Please enter a valid latitude. A valid latitude is comprised between +90 and -90.'), 'error_message_not_valid_long' => Ai1ec_I18n::__('Please enter a valid longitude. A valid longitude is comprised between +180 and -180.'), 'error_message_not_entered_lat' => Ai1ec_I18n::__('When the "Input coordinates" checkbox is checked, "Latitude" is a required field.'), 'error_message_not_entered_long' => Ai1ec_I18n::__('When the "Input coordinates" checkbox is checked, "Longitude" is a required field.'), 'ai1ec_contact_url_not_valid' => Ai1ec_I18n::__('The URL you have entered in the <b>Organizer Contact Info</b> > <b>Website URL</b> seems to be invalid.'), 'ai1ec_ticket_url_not_valid' => Ai1ec_I18n::__('The URL you have entered in the <b>Event Cost and Tickets</b> > <b>Buy Tickets URL</b> seems to be invalid.'), 'general_url_not_valid' => Ai1ec_I18n::__('Please remember that URLs must start with either "http://" or "https://".'), 'calendar_loading' => Ai1ec_I18n::__('Loading…'), 'ticketing_required_fields' => Ai1ec_I18n::__('<p class="ai1ec_ticketing_required_alert"><b>Some fields required for Ticketing are missing.</b><br><i>Missing or incorrect fields are outlined red.</i></p>'), 'language' => $this->_registry->get('p28n.wpml')->get_lang(), 'ajax_url' => $ajax_url, 'twentyfour_hour' => $settings->get('input_24h_time'), 'date_format' => $settings->get('input_date_format'), 'month_names' => $locale->get_localized_month_names(), 'day_names' => $locale->get_localized_week_names(), 'week_start_day' => $settings->get('week_start_day'), 'week_view_starts_at' => $settings->get('week_view_starts_at'), 'week_view_ends_at' => $settings->get('week_view_ends_at'), 'blog_timezone' => $blog_timezone, 'affix_filter_menu' => $settings->get('affix_filter_menu'), 'affix_vertical_offset_md' => $settings->get('affix_vertical_offset_md'), 'affix_vertical_offset_lg' => $settings->get('affix_vertical_offset_lg'), 'affix_vertical_offset_sm' => $settings->get('affix_vertical_offset_sm'), 'affix_vertical_offset_xs' => $settings->get('affix_vertical_offset_xs'), 'calendar_page_id' => $settings->get('calendar_page_id'), 'region' => $settings->get('geo_region_biasing') ? $locale->get_region() : '', 'site_url' => trailingslashit(ai1ec_get_site_url()), 'javascript_widgets' => array(), 'widget_creator' => array('preview' => Ai1ec_I18n::__('Preview:'), 'preview_loading' => Ai1ec_I18n::__('Loading preview <i class="ai1ec-fa ai1ec-fa-spin ai1ec-fa-spinner"></i>')), 'ticketing' => array('details' => Ai1ec_I18n::__('Ticketing Details'), 'hide_details' => Ai1ec_I18n::__('Hide Ticketing Details'), 'loading_details' => Ai1ec_I18n::__('Loading tickets details...'), 'type_and_price' => Ai1ec_I18n::__('Type and price'), 'info' => Ai1ec_I18n::__('Info'), 'report' => Ai1ec_I18n::__('Report'), 'sale_dates' => Ai1ec_I18n::__('Sale dates'), 'limits' => Ai1ec_I18n::__('Limits'), 'actions' => Ai1ec_I18n::__('Actions'), 'sold' => Ai1ec_I18n::__('Sold:'), 'left' => Ai1ec_I18n::__('Left:'), 'start' => Ai1ec_I18n::__('Start:'), 'end' => Ai1ec_I18n::__('End:'), 'min' => Ai1ec_I18n::__('Min:'), 'max' => Ai1ec_I18n::__('Max:'), 'attendees' => Ai1ec_I18n::__('Attendees'), 'hide_attendees' => Ai1ec_I18n::__('Hide Attendees'), 'attendees_list' => Ai1ec_I18n::__('Attendees List'), 'guest_name' => Ai1ec_I18n::__('Guest Name'), 'status' => Ai1ec_I18n::__('Status'), 'email' => Ai1ec_I18n::__('Email'), 'no_attendees' => Ai1ec_I18n::__('No attendees for this ticket type.'), 'edit' => Ai1ec_I18n::__('Edit'), 'code' => Ai1ec_I18n::__('Code'), 'unlimited' => Ai1ec_I18n::__('Unlimited')), 'review' => array('message_sent' => Ai1ec_I18n::__('Your message has been sent. Thank you for your feedback.'), 'message_error' => Ai1ec_I18n::__('Your message has not been sent. Please try again or contact us.')), 'load_views_error' => Ai1ec_I18n::__('Something went wrong while fetching events.<br>The request status is: %STATUS% <br>The error thrown was: %ERROR%'), 'load_views_error_popup_title' => Ai1ec_I18n::__('Response text received from server'), 'load_views_error_link_popup' => Ai1ec_I18n::__('Click here for technical details'), 'cookie_path' => $this->_registry->get('cookie.utility')->get_path_for_cookie(), 'disable_autocompletion' => $settings->get('disable_autocompletion'), 'end_must_be_after_start' => __('The end date can\'t be earlier than the start date.', AI1EC_PLUGIN_NAME), 'show_at_least_six_hours' => __('For week and day view, you must select an interval of at least 6 hours.', AI1EC_PLUGIN_NAME), 'ai1ec_permalinks_enabled' => $application->get('permalinks_enabled')); return apply_filters('ai1ec_js_translations', $data); }
/** * Create a duplicate from a posts' instance */ public function duplicate_post_create_duplicate($post, $status = '') { $post = get_post($post); $new_post_author = $this->_duplicate_post_get_current_user(); $new_post_status = $status; if (empty($new_post_status)) { $new_post_status = $post->post_status; } $new_post_status = $this->_get_new_post_status($new_post_status); $new_post = array('menu_order' => $post->menu_order, 'comment_status' => $post->comment_status, 'ping_status' => $post->ping_status, 'pinged' => $post->pinged, 'post_author' => $new_post_author->ID, 'post_content' => $post->post_content, 'post_date' => $post->post_date, 'post_date_gmt' => get_gmt_from_date($post->post_date), 'post_excerpt' => $post->post_excerpt, 'post_parent' => $post->post_parent, 'post_password' => $post->post_password, 'post_status' => $new_post_status, 'post_title' => $post->post_title, 'post_type' => $post->post_type, 'to_ping' => $post->to_ping); $new_post_id = wp_insert_post($new_post); $edit_event_url = esc_attr(ai1ec_admin_url("post.php?post={$new_post_id}&action=edit")); $message = sprintf(__('<p>The event <strong>%s</strong> was cloned succesfully. <a href="%s">Edit cloned event</a></p>', AI1EC_PLUGIN_NAME), $post->post_title, $edit_event_url); $notification = $this->_registry->get('notification.admin'); $notification->store($message); $this->_duplicate_post_copy_post_taxonomies($new_post_id, $post); $this->_duplicate_post_copy_attachments($new_post_id, $post); $this->_duplicate_post_copy_post_meta_info($new_post_id, $post); if ($this->_registry->get('acl.aco')->is_our_post_type($post)) { try { $old_event = $this->_registry->get('model.event', $post->ID); $old_event->set('post_id', $new_post_id); $old_event->set('post', null); $old_event->set('ical_feed_url', null); $old_event->set('ical_source_url', null); $old_event->set('ical_organizer', null); $old_event->set('ical_contact', null); $old_event->set('ical_uid', null); $old_event->save(); } catch (Ai1ec_Event_Not_Found_Exception $exception) { /* ignore */ } } $meta_post = $this->_registry->get('model.meta-post'); $meta_post->delete($new_post_id, '_dp_original'); $meta_post->add($new_post_id, '_dp_original', $post->ID); // If the copy gets immediately published, we have to set a proper slug. if ($new_post_status == 'publish' || $new_post_status == 'future') { $post_name = wp_unique_post_slug($post->post_name, $new_post_id, $new_post_status, $post->post_type, $post->post_parent); $new_post = array(); $new_post['ID'] = $new_post_id; $new_post['post_name'] = $post_name; // Update the post into the database wp_update_post($new_post); } return $new_post_id; }
/** * Attempt to decode GMT offset to some Olson timezone. * * @param float $zone GMT offset. * * @return string Valid Olson timezone name (UTC is last resort). */ public function decode_gmt_timezone($zone) { $auto_zone = timezone_name_from_abbr(null, $zone * 3600, true); if (false !== $auto_zone) { return $auto_zone; } $auto_zone = timezone_name_from_abbr(null, (int) $zone * 3600, true); if (false !== $auto_zone) { return $auto_zone; } $this->_registry->get('notification.admin')->store(sprintf(Ai1ec_I18n::__('Timezone "UTC%+d" is not recognized. Please %suse valid%s timezone name, until then events will be created in UTC timezone.'), $zone, '<a href="' . ai1ec_admin_url('options-general.php') . '">', '</a>'), 'error'); return 'UTC'; }
/** * Adds a link to Settings page in plugin list page. * * @param array $links List of available links. * * @return array Modified links list. */ public function plugin_action_links($links) { $settings_link = sprintf(Ai1ec_I18n::__('<a href="%s">Settings</a>'), ai1ec_admin_url(AI1EC_SETTINGS_BASE_URL)); array_unshift($links, $settings_link); return $links; }
/** * Set the default theme if no theme is set, or populate theme info array if * insufficient information is currently being stored. * * @uses apply_filters() Calls 'ai1ec_pre_save_current_theme' hook to allow * overwriting of theme information before being stored. */ protected function _add_default_theme_if_not_set() { $option = $this->_registry->get('model.option'); $theme = $option->get('ai1ec_current_theme', array()); $update = false; // Theme setting is undefined; default to Vortex. if (empty($theme)) { $theme = $this->_default_theme; $update = true; } else { if (is_string($theme)) { $theme_name = strtolower($theme); $core_themes = explode(',', AI1EC_CORE_THEMES); $legacy = !in_array($theme_name, $core_themes); if ($legacy) { $root = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . AI1EC_THEME_FOLDER; $url = WP_CONTENT_URL . '/' . AI1EC_THEME_FOLDER . '/' . $theme_name; } else { $root = AI1EC_DEFAULT_THEME_ROOT; $url = AI1EC_THEMES_URL . '/' . $theme_name; } // if it's from 1.x, move folders to avoid confusion if (apply_filters('ai1ec_move_themes_to_backup', true)) { $this->_registry->get('theme.search')->move_themes_to_backup($core_themes); } // Ensure existence of theme directory. if (!is_dir($root . DIRECTORY_SEPARATOR . $theme_name)) { // It's missing; something is wrong with this theme. Reset theme to // Vortex and warn the user accordingly. $option->set('ai1ec_current_theme', $this->_default_theme); $notification = $this->_registry->get('notification.admin'); $notification->store(sprintf(Ai1ec_I18n::__('Your active calendar theme could not be properly initialized. The default theme has been activated instead. Please visit %s and try reactivating your theme manually.'), '<a href="' . ai1ec_admin_url(AI1EC_THEME_SELECTION_BASE_URL) . '">' . Ai1ec_I18n::__('Calendar Themes') . '</a>'), 'error', 1); } $theme = array('theme_dir' => $root . DIRECTORY_SEPARATOR . $theme_name, 'theme_root' => $root, 'theme_url' => $url, 'stylesheet' => $theme_name, 'legacy' => $legacy); $update = true; } else { if (!isset($theme['theme_url'])) { if ($theme['legacy']) { $theme['theme_url'] = WP_CONTENT_URL . '/' . AI1EC_THEME_FOLDER . '/' . $theme['stylesheet']; } else { $theme['theme_url'] = AI1EC_THEMES_URL . '/' . $theme['stylesheet']; } $update = true; } } } if ($update) { $theme = apply_filters('ai1ec_pre_save_current_theme', $theme); $option->set('ai1ec_current_theme', $theme); } }
public function do_execute() { $this->_registry->get('model.settings')->set('disable_gzip_compression', true); return array('url' => ai1ec_admin_url('edit.php'), 'query_args' => array('post_type' => 'ai1ec_event', 'page' => 'all-in-one-event-calendar-settings')); }
/** * Create the array needed for translation and passing other settings to JS. * * @return $data array the dynamic data array */ public function get_translation_data() { $force_ssl_admin = force_ssl_admin(); if ($force_ssl_admin && !is_ssl()) { force_ssl_admin(false); } $ajax_url = ai1ec_admin_url('admin-ajax.php'); force_ssl_admin($force_ssl_admin); $settings = $this->_registry->get('model.settings'); $locale = $this->_registry->get('p28n.wpml'); $blog_timezone = $this->_registry->get('model.option')->get('gmt_offset'); $data = array('calendar_feeds_nonce' => wp_create_nonce('ai1ec_ics_feed_nonce'), 'duplicate_feed_message' => esc_html(Ai1ec_I18n::__('This feed is already being imported.')), 'invalid_url_message' => esc_html(Ai1ec_I18n::__('Please enter a valid iCalendar URL.')), 'invalid_email_message' => esc_html(Ai1ec_I18n::__('Please enter a valid email address.')), 'choose_image_message' => Ai1ec_I18n::__('Choose Image'), 'now' => $this->_registry->get('date.system')->current_time(), 'size_less_variable_not_ok' => Ai1ec_I18n::__('The value you have entered is not a valid CSS length.'), 'confirm_reset_theme' => Ai1ec_I18n::__('Are you sure you want to reset your theme options to their default values?'), 'error_message_not_valid_lat' => Ai1ec_I18n::__('Please enter a valid latitude. A valid latitude is comprised between +90 and -90.'), 'error_message_not_valid_long' => Ai1ec_I18n::__('Please enter a valid longitude. A valid longitude is comprised between +180 and -180.'), 'error_message_not_entered_lat' => Ai1ec_I18n::__('When the "Input coordinates" checkbox is checked, "Latitude" is a required field.'), 'error_message_not_entered_long' => Ai1ec_I18n::__('When the "Input coordinates" checkbox is checked, "Longitude" is a required field.'), 'ai1ec_contact_url_not_valid' => Ai1ec_I18n::__('The URL you have entered in the <b>Organizer Contact Info</b> > <b>External URL</b> seems to be invalid.'), 'ai1ec_ticket_url_not_valid' => Ai1ec_I18n::__('The URL you have entered in the <b>Event Cost and Tickets</b> > <b>Buy Tickets URL</b> seems to be invalid.'), 'general_url_not_valid' => Ai1ec_I18n::__('Please remember that URLs must start with either "http://" or "https://".'), 'calendar_loading' => Ai1ec_I18n::__('Loading…'), 'language' => $this->_registry->get('p28n.wpml')->get_lang(), 'ajax_url' => $ajax_url, 'twentyfour_hour' => $settings->get('input_24h_time'), 'date_format' => $settings->get('input_date_format'), 'month_names' => $locale->get_localized_month_names(), 'day_names' => $locale->get_localized_week_names(), 'week_start_day' => $settings->get('week_start_day'), 'week_view_starts_at' => $settings->get('week_view_starts_at'), 'week_view_ends_at' => $settings->get('week_view_ends_at'), 'blog_timezone' => $blog_timezone, 'affix_filter_menu' => $settings->get('affix_filter_menu'), 'affix_vertical_offset_md' => $settings->get('affix_vertical_offset_md'), 'affix_vertical_offset_lg' => $settings->get('affix_vertical_offset_lg'), 'affix_vertical_offset_sm' => $settings->get('affix_vertical_offset_sm'), 'affix_vertical_offset_xs' => $settings->get('affix_vertical_offset_xs'), 'calendar_page_id' => $settings->get('calendar_page_id'), 'region' => $settings->get('geo_region_biasing') ? $locale->get_region() : '', 'site_url' => trailingslashit(ai1ec_get_site_url()), 'javascript_widgets' => array(), 'widget_creator' => array('preview' => Ai1ec_I18n::__('Preview:'), 'preview_loading' => Ai1ec_I18n::__('Loading preview <i class="ai1ec-fa ai1ec-fa-spin ai1ec-fa-spinner"></i>')), 'load_views_error' => Ai1ec_I18n::__('Something went wrong while fetching events.<br>The request status is: %STATUS% <br>The error thrown was: %ERROR%'), 'cookie_path' => $this->_registry->get('cookie.utility')->get_path_for_cookie(), 'disable_autocompletion' => $settings->get('disable_autocompletion'), 'end_must_be_after_start' => __('The end date can\'t be earlier than the start date.', AI1EC_PLUGIN_NAME), 'show_at_least_six_hours' => __('For week and day view, you must select an interval of at least 6 hours.', AI1EC_PLUGIN_NAME)); return apply_filters('ai1ec_js_translations', $data); }
<div class="wrap"> <?php screen_icon(); if (!is_multisite() && current_user_can('install_themes')) { ?> <h2 class="nav-tab-wrapper"> <a href="<?php echo ai1ec_admin_url(AI1EC_THEME_SELECTION_BASE_URL); ?> " class="nav-tab nav-tab-active"> <?php echo esc_html(__('Manage Themes')); ?> </a> <a href="<?php echo ai1ec_admin_url(AI1EC_THEME_SELECTION_BASE_URL . '-install'); ?> " class="nav-tab"> <?php echo esc_html_x('Install Themes', 'theme'); ?> </a> </h2> <?php } else { ?> <h2><?php echo esc_html(__('Manage Themes')); ?> </h2> <?php
/** * @see Ai1ec_Exception::get_redirect_url() */ public function get_redirect_url() { return ai1ec_admin_url('plugins.php'); }
/** * Get the url of the page * * @return string */ public function get_url() { return add_query_arg(array('post_type' => AI1EC_POST_TYPE, 'page' => AI1EC_PLUGIN_NAME . '-' . $this->_page_suffix), ai1ec_admin_url('edit.php')); }
/** * display_rows function * * @return void **/ function display_rows() { $themes = $this->items; $theme_names = array_keys($themes); natcasesort($theme_names); foreach ($theme_names as $theme_name) { $class = array('available-theme'); ?> <div class="<?php echo join(' ', $class); ?> "> <?php if (!empty($theme_name)) { $template = $themes[$theme_name]['Template']; $stylesheet = $themes[$theme_name]['Stylesheet']; $title = $themes[$theme_name]['Title']; $version = $themes[$theme_name]['Version']; $description = $themes[$theme_name]['Description']; $author = $themes[$theme_name]['Author']; $screenshot = $themes[$theme_name]['Screenshot']; $stylesheet_dir = $themes[$theme_name]['Stylesheet Dir']; $template_dir = $themes[$theme_name]['Template Dir']; $parent_theme = $themes[$theme_name]['Parent Theme']; $theme_root = $themes[$theme_name]['Theme Root']; $theme_dir = $themes[$theme_name]->get_stylesheet_directory(); $theme_root_uri = esc_url($themes[$theme_name]['Theme Root URI']); $tags = $themes[$theme_name]['Tags']; // Generate theme activation link. $activate_link = ai1ec_admin_url(AI1EC_THEME_SELECTION_BASE_URL); $activate_link = add_query_arg(array('ai1ec_action' => 'activate_theme', 'ai1ec_theme_dir' => $theme_dir, 'ai1ec_legacy' => false, 'ai1ec_stylesheet' => $stylesheet, 'ai1ec_theme_root' => $theme_root, 'ai1ec_theme_url' => $theme_root_uri . '/' . $stylesheet), $activate_link); $activate_link = wp_nonce_url($activate_link, 'switch-ai1ec_theme_' . $template); $activate_text = esc_attr(sprintf(Ai1ec_I18n::__('Activate “%s”'), $title)); $actions = array(); $actions[] = '<a href="' . $activate_link . '" class="activatelink" title="' . $activate_text . '">' . Ai1ec_I18n::__('Activate') . '</a>'; $actions = apply_filters('theme_action_links', $actions, $themes[$theme_name]); $actions = implode(' | ', $actions); ?> <?php if ($screenshot) { ?> <img src="<?php echo $theme_root_uri . '/' . $stylesheet . '/' . $screenshot; ?> " alt="" /> <?php } ?> <h3> <?php /* translators: 1: theme title, 2: theme version, 3: theme author */ printf(Ai1ec_I18n::__('%1$s %2$s by %3$s'), $title, $version, $author); ?> </h3> <p class="description"><?php echo $description; ?> </p> <span class='action-links'><?php echo $actions; ?> </span> <?php if (current_user_can('edit_themes') && $parent_theme) { /* translators: 1: theme title, 2: template dir, 3: stylesheet_dir, 4: theme title, 5: parent_theme */ ?> <p> <?php printf(Ai1ec_I18n::__('The template files are located in <code>%2$s</code>. The stylesheet files are located in <code>%3$s</code>. <strong>%4$s</strong> uses templates from <strong>%5$s</strong>. Changes made to the templates will affect both themes.'), $title, str_replace(WP_CONTENT_DIR, '', $template_dir), str_replace(WP_CONTENT_DIR, '', $stylesheet_dir), $title, $parent_theme); ?> </p> <?php } else { ?> <p> <?php printf(Ai1ec_I18n::__('All of this theme’s files are located in <code>%2$s</code>.'), $title, str_replace(WP_CONTENT_DIR, '', $template_dir), str_replace(WP_CONTENT_DIR, '', $stylesheet_dir)); ?> </p> <?php } ?> <?php if ($tags) { ?> <p> <?php echo Ai1ec_I18n::__('Tags:'); ?> <?php echo join(', ', $tags); ?> </p> <?php } ?> <?php } // end if not empty theme_name ?> </div> <?php } // end foreach $theme_names }