all-in-one-event-calendar/app/model/settings.php
2019-07-25 14:11:00 +02:00

1107 lines
42 KiB
PHP

<?php
/**
* Model used for storing/retrieving plugin options.
*
* @author Time.ly Network, Inc.
* @since 2.0
* @package Ai1EC
* @subpackage Ai1EC.Model
*/
class Ai1ec_Settings extends Ai1ec_App {
/**
* @constant string Name of WordPress options key used to store settings.
*/
const WP_OPTION_KEY = 'ai1ec_settings';
/**
* @var array Map of value names and their representations.
*/
protected $_options = array();
/**
* @var bool Indicator for modified object state.
*/
protected $_updated = false;
/**
* @var array The core options of the plugin.
*/
protected $_standard_options;
/**
* Register new option to be used.
*
* @param string $option Name of option.
* @param mixed $value The value.
* @param string $type Option type to be used for validation.
* @param string $renderer Name of class to render the option.
*
* @return Ai1ec_Settings Instance of self for chaining.
*/
public function register(
$option,
$value,
$type,
$renderer,
$version = '2.0.0'
) {
if ( 'deprecated' === $type ) {
unset( $this->_options[$option] );
} else if (
! isset( $this->_options[$option] ) ||
! isset( $this->_options[$option]['version'] ) ||
(string)$this->_options[$option]['version'] !== (string)$version ||
(
isset( $renderer['label'] ) &&
isset( $this->_options[$option]['renderer'] ) &&
(string)$this->_options[$option]['renderer']['label'] !== (string)$renderer['label']
) ||
(
isset( $renderer['help'] ) &&
( ! isset( $this->_options[$option]['renderer']['help'] ) || // handle the case when you are adding help
(string)$this->_options[$option]['renderer']['help'] !== (string)$renderer['help'] )
)
) {
$this->_options[$option] = array(
'value' => ( isset( $this->_options[$option] ) )
? $this->_options[$option]['value']
: $value,
'type' => $type,
'legacy' => false,
'version' => $version,
);
if ( null !== $renderer ) {
$this->_options[$option]['renderer'] = $renderer;
}
}
return $this;
}
/**
* Gets the options.
*
* @return array:
*/
public function get_options() {
return $this->_options;
}
/**
* Get field options as registered.
*
* @param string $option Name of option field to describe.
*
* @return array|null Description or null if nothing is found.
*/
public function describe( $option ) {
if ( ! isset( $this->_options[$option] ) ) {
return null;
}
return $this->_options[$option];
}
/**
* Get value for option.
*
* @param string $option Name of option to get value for.
* @param mixed $default Value to return if option is not found.
*
* @return mixed Value or $default if none is found.
*/
public function get( $option, $default = null ) {
// notice, that `null` is not treated as a value
if ( ! isset( $this->_options[$option] ) ) {
return $default;
}
return $this->_options[$option]['value'];
}
/**
* Set new value for previously initialized option.
*
* @param string $option Name of option to update.
* @param mixed $value Actual value to be used for option.
*
* @throws Ai1ec_Settings_Exception
*
* @return Ai1ec_Settings Instance of self for chaining.
*/
public function set( $option, $value ) {
if ( ! isset( $this->_options[$option] ) ) {
throw new Ai1ec_Settings_Exception(
'Option "' . $option . '" was not registered'
);
}
if ( 'array' === $this->_options[$option]['type'] ) {
if (
! is_array( $this->_options[$option]['value'] ) ||
! is_array( $value ) ||
$value != $this->_options[$option]['value']
) {
$this->_options[$option]['value'] = $value;
$this->_change_update_status ( true );
}
} else if (
(string)$value !== (string)$this->_options[$option]['value']
) {
$this->_options[$option]['value'] = $value;
$this->_change_update_status ( true );
}
return $this;
}
/**
* Parse legacy values into new structure.
*
* @param mixed $values Expected legacy representation.
*
* @return array Parsed values representation, or input cast as array.
*/
protected function _parse_legacy( Ai1ec_Settings $values ) {
$variables = get_object_vars( $values );
$default_tags_cat = array();
$legacy = array();
foreach ( $variables as $key => $value ) {
if ( 'default_categories' === $key ) {
$default_tags_cat['categories'] = $value;
continue;
}
if ( 'default_tags' === $key ) {
$default_tags_cat['tags'] = $value;
continue;
}
$type = 'string';
if ( is_array( $value ) ) {
$type = 'array';
} elseif ( is_bool( $value ) ) {
$type = 'bool';
} elseif ( is_int( $value ) ) {
$type = 'int';
}
if ( isset( $this->_options[$key] ) ) {
$this->_options[$key]['value'] = $value;
} else {
$legacy[$key] = array(
'value' => $value,
'type' => $type,
'legacy' => true,
'version' => AI1EC_VERSION
);
}
}
$this->_options['default_tags_categories']['value'] = $default_tags_cat;
$this->_options['legacy_options'] = $legacy;
}
/**
* Write object representation to persistence layer.
*
* Upon successful write to persistence layer the objects internal
* state {@see self::$_updated} is updated respectively.
*
* @return bool Success.
*/
public function persist() {
$success = $this->_registry->get( 'model.option' )
->set( self::WP_OPTION_KEY, $this->_options );
if ( $success ) {
$this->_change_update_status( false );
}
return $success;
}
/**
* Remove an option if is set.
*
* @param string $option
*/
public function remove_option( $option ) {
if ( isset( $this->_options[$option] ) ) {
unset( $this->_options[$option] );
$this->_change_update_status( true );
}
}
/**
* Do things needed on every plugin upgrade.
*/
public function perform_upgrade_actions() {
update_option( 'ai1ec_force_flush_rewrite_rules', true );
update_option( 'ai1ec_invalidate_css_cache', true );
update_option( Ai1ec_Theme_Loader::OPTION_FORCE_CLEAN, true );
}
/**
* Hide an option by unsetting it's renderer
*
* @param string $option
*/
public function hide_option( $option ) {
if ( isset( $this->_options[$option] ) ) {
unset( $this->_options[$option]['renderer'] );
$this->_change_update_status( true );
}
}
/**
* Show an option by setting it's renderer
*
* @param string $option
*/
public function show_option( $option, array $renderer ) {
if ( isset( $this->_options[$option] ) ) {
$this->_options[$option]['renderer'] = $renderer;
$this->_change_update_status( true );
}
}
/**
* Check object state and update it's database representation as needed.
*
* @return void Destructor does not return.
*/
public function shutdown() {
if ( $this->_updated ) {
$this->persist();
}
}
/**
* Observes wp_options changes. If any matches related setting then
* updates that setting.
*
* @param string $option Name of the updated option.
* @param mixed $old_value The old option value.
* @param mixed $value The new option value.
*
* @return void Method does not return.
*/
public function wp_options_observer( $option, $old_value, $value ) {
$options = $this->get_options();
if (
self::WP_OPTION_KEY === $option ||
empty( $options )
) {
return;
}
if (
isset( $options[$option] ) &&
'wp_option' === $options[$option]['type'] &&
$this->get( $option ) !== $value
) {
$this->set( $option, $value );
}
}
/**
* Initiate options map from storage.
*
* @return void Return from this method is ignored.
*/
protected function _initialize() {
$this->_set_standard_values();
$values = $this->_registry->get( 'model.option' )
->get( self::WP_OPTION_KEY, array() );
$this->_change_update_status( false );
$test_version = false;
if ( is_array( $values ) ) { // always assign existing values, if any
$this->_options = $values;
if ( isset( $values['calendar_page_id'] ) ) {
$test_version = $values['calendar_page_id']['version'];
}
}
// check for updated translations
$this->_register_standard_values();
if ( // process meta updates changes
empty( $values ) || (
false !== $test_version &&
AI1EC_VERSION !== $test_version
)
) {
$this->_register_standard_values();
$this->_update_name_translations();
$this->_change_update_status( true );
} else if ( $values instanceof Ai1ec_Settings ) { // process legacy
$this->_parse_legacy( $values );
$this->_change_update_status( true );
}
$this->_registry->get( 'controller.shutdown' )->register(
array( $this, 'shutdown' )
);
}
/**
* Set the standard values for the options of the core plugin.
*
*/
protected function _set_standard_values() {
$this->_standard_options = array(
'enabling_ticket_invitation_page' => array(
'type' => 'string',
'default' => false,
),
'ai1ec_api' => array(
'type' => 'boolean',
'default' => false,
),
'ai1ec_db_version' => array(
'type' => 'int',
'default' => false,
),
'feeds_page' => array(
'type' => 'string',
'default' => false,
),
'settings_page' => array(
'type' => 'string',
'default' => false,
),
'less_variables_page' => array(
'type' => 'string',
'default' => false,
),
'input_date_format' => array(
'type' => 'string',
'default' => 'd/m/yyyy',
),
'plugins_options' => array(
'type' => 'array',
'default' => array(),
),
'show_tracking_popup' => array(
'type' => 'deprecated',
'default' => true,
),
'ticketing_message' => array(
'type' => 'string',
'default' => false,
),
'ticketing_token' => array(
'type' => 'string',
'default' => '',
),
'ticketing_enabled' => array(
'type' => 'boolean',
'default' => false,
),
'ticketing_calendar_id' => array(
'type' => 'int',
'default' => 0,
),
'calendar_page_id' => array(
'type' => 'mixed',
'renderer' => array(
'class' => 'calendar-page-selector',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__( 'Calendar page' )
),
'default' => false,
),
'week_start_day' => array(
'type' => 'int',
'renderer' => array(
'class' => 'select',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__( 'Week starts on' ),
'options' => 'get_weekdays',
),
'default' => $this->_registry->get( 'model.option' )->get(
'start_of_week'
),
),
'enabled_views' => array(
'type' => 'array',
'renderer' => array(
'class' => 'enabled-views',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__( 'Available views' ),
),
'default' => array(
'agenda' => array(
'enabled' => true,
'default' => true,
'enabled_mobile' => true,
'default_mobile' => true,
'longname' => _n_noop(
'Agenda',
'Agenda',
AI1EC_PLUGIN_NAME
),
),
'oneday' => array(
'enabled' => true,
'default' => false,
'enabled_mobile' => true,
'default_mobile' => false,
'longname' => _n_noop(
'Day',
'Day',
AI1EC_PLUGIN_NAME
),
),
'month' => array(
'enabled' => true,
'default' => false,
'enabled_mobile' => true,
'default_mobile' => false,
'longname' => _n_noop(
'Month',
'Month',
AI1EC_PLUGIN_NAME
),
),
'week' => array(
'enabled' => true,
'default' => false,
'enabled_mobile' => true,
'default_mobile' => false,
'longname' => _n_noop(
'Week',
'Week',
AI1EC_PLUGIN_NAME
),
),
),
),
'timezone_string' => array(
'type' => 'wp_option',
'renderer' => array(
'class' => 'select',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__( 'Timezone' ),
'options' => 'Ai1ec_Date_Timezone:get_timezones',
),
'default' => $this->_registry->get( 'model.option' )->get(
'timezone_string'
),
),
'default_tags_categories' => array(
'type' => 'array',
'renderer' => array(
'class' => 'tags-categories',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__( 'Preselected calendar filters' ),
'help' => Ai1ec_I18n::__(
'To clear, hold &#8984;/<abbr class="initialism">CTRL</abbr> and click selection.'
)
),
'default' => array(
'categories' => array(),
'tags' => array(),
),
),
'exact_date' => array(
'type' => 'string',
'renderer' => array(
'class' => 'input',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__( 'Default calendar start date (optional)' ),
'type' => 'date',
),
'default' => '',
),
'agenda_events_per_page' => array(
'type' => 'int',
'renderer' => array(
'class' => 'input',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__( 'Agenda pages show at most' ),
'type' => 'append',
'append' => 'events',
'validator' => 'numeric',
),
'default' => 10,
),
'week_view_starts_at' => array(
'type' => 'int',
'renderer' => array(
'class' => 'input',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__( 'Week/Day view starts at' ),
'type' => 'append',
'append' => 'hrs',
'validator' => 'numeric',
),
'default' => 8,
),
'week_view_ends_at' => array(
'type' => 'int',
'renderer' => array(
'class' => 'input',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__( 'Week/Day view ends at' ),
'type' => 'append',
'append' => 'hrs',
'validator' => 'numeric',
),
'default' => 24,
),
'google_maps_api_key' => array(
'type' => 'string',
'renderer' => array(
'class' => 'input',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__(
'<span class="ai1ec-tooltip-toggle"
data-original-title="Google may request for an API key in order to show the map">
Google Maps API Key</span> (<a target="_blank" href="https://developers.google.com/maps/documentation/javascript/get-api-key#get-an-api-key">Get an API key</a>)'
),
'type' => 'normal'
),
'default' => '',
),
'month_word_wrap' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__(
'<strong>Word-wrap event stubs</strong> in Month view'
),
'help' => Ai1ec_I18n::__(
'Only applies to events that span a single day.'
),
),
'default' => false,
),
'agenda_include_entire_last_day' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__(
'In <span class="ai1ec-tooltip-toggle"
data-original-title="These include Agenda view,
the Upcoming Events widget, and some extended views.">
Agenda-like views</span>, <strong>include all events
from last day shown</strong>'
)
),
'default' => false,
),
'agenda_events_expanded' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__(
'Keep all events <strong>expanded</strong> in Agenda view'
)
),
'default' => false,
),
'show_year_in_agenda_dates' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__(
'<strong>Show year</strong> in calendar date labels'
)
),
'default' => false,
),
'show_location_in_title' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__(
'<strong>Show location in event titles</strong> in calendar views'
)
),
'default' => true,
),
'exclude_from_search' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__(
'<strong>Exclude</strong> events from search results'
)
),
'default' => false,
),
'turn_off_subscription_buttons' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__(
'Hide <strong>Subscribe</strong>/<strong>Add to Calendar</strong> buttons in calendar and single event views '
)
),
'default' => false,
),
'disable_get_calendar_button' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__(
'Hide <strong>Get a Timely Calendar</strong> button'
)
),
'default' => true,
),
'hide_maps_until_clicked' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__(
' Hide <strong>Google Maps</strong> until clicked'
)
),
'default' => false,
),
'affix_filter_menu' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__(
' <strong>Affix filter menu</strong> to top of window when it scrolls out of view'
),
'help' => Ai1ec_I18n::__(
'Only applies to first visible calendar found on the page.'
),
),
'default' => false,
),
'affix_vertical_offset_md' => array(
'type' => 'int',
'renderer' => array(
'class' => 'input',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__( 'Offset affixed filter bar vertically by' ),
'type' => 'append',
'append' => 'pixels',
'validator' => 'numeric',
),
'default' => 0,
),
'affix_vertical_offset_lg' => array(
'type' => 'int',
'renderer' => array(
'class' => 'input',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' =>
'<i class="ai1ec-fa ai1ec-fa-lg ai1ec-fa-fw ai1ec-fa-desktop"></i> ' .
Ai1ec_I18n::__( 'Wide screens only (&#8805; 1200px)' ),
'type' => 'append',
'append' => 'pixels',
'validator' => 'numeric',
),
'default' => 0,
),
'affix_vertical_offset_sm' => array(
'type' => 'int',
'renderer' => array(
'class' => 'input',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' =>
'<i class="ai1ec-fa ai1ec-fa-lg ai1ec-fa-fw ai1ec-fa-tablet"></i> ' .
Ai1ec_I18n::__( 'Tablets only (< 980px)' ),
'type' => 'append',
'append' => 'pixels',
'validator' => 'numeric',
),
'default' => 0,
),
'affix_vertical_offset_xs' => array(
'type' => 'int',
'renderer' => array(
'class' => 'input',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' =>
'<i class="ai1ec-fa ai1ec-fa-lg ai1ec-fa-fw ai1ec-fa-mobile"></i> ' .
Ai1ec_I18n::__( 'Phones only (< 768px)' ),
'type' => 'append',
'append' => 'pixels',
'validator' => 'numeric',
),
'default' => 0,
),
'strict_compatibility_content_filtering' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__(
'Strict compatibility content filtering'
),
),
'default' => false,
),
'hide_featured_image' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__(
' <strong>Hide featured image</strong> from event details page'
),
'help' => Ai1ec_I18n::__(
"Select this option if your theme already displays each post's featured image."
),
),
'default' => false,
),
'input_date_format' => array(
'type' => 'string',
'renderer' => array(
'class' => 'select',
'tab' => 'editing-events',
'label' => Ai1ec_I18n::__(
'Input dates in this format'
),
'options' => array(
array(
'text' => Ai1ec_I18n::__( 'Default (d/m/yyyy)' ),
'value' => 'def'
),
array(
'text' => Ai1ec_I18n::__( 'US (m/d/yyyy)' ),
'value' => 'us'
),
array(
'text' => Ai1ec_I18n::__( 'ISO 8601 (yyyy-m-d)' ),
'value' => 'iso'
),
array(
'text' => Ai1ec_I18n::__( 'Dotted (m.d.yyyy)' ),
'value' => 'dot'
),
),
),
'default' => 'def',
),
'input_24h_time' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'editing-events',
'label' => Ai1ec_I18n::__(
' Use <strong>24h time</strong> in time pickers'
)
),
'default' => false,
),
'disable_autocompletion' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'editing-events',
'label' => Ai1ec_I18n::__(
'<strong>Disable address autocomplete</strong> function'
)
),
'default' => false,
),
'geo_region_biasing' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'editing-events',
'label' => Ai1ec_I18n::__(
'Use the configured <strong>region</strong> (WordPress locale) to bias the address autocomplete function '
)
),
'default' => false,
),
'show_publish_button' => array(
'type' => 'deprecated',
'renderer' => null,
'default' => false,
),
'show_create_event_button' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'extensions',
'label' => Ai1ec_I18n::__(
' Show the old <strong>Post Your Event</strong> button above the calendar to privileged users'
),
'help' => Ai1ec_I18n::__(
'Install the <a target="_blank" href="https://time.ly/">Interactive Frontend Extension</a> for the <strong>frontend Post Your Event form</strong>.'
),
),
'default' => true,
),
'twitterinfo' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'extensions',
'item' => 'twittertab',
'label' => '',
'help' => Ai1ec_I18n::__(
'<div class="ai1ec-twitterinfo-wrap"><b>Twitter</b><br>This feature allows your events to be automatically tweeted before they happen. Great way to add regular content to your twitter roll and keep your audience informed of all your great events. This feature is not yet enabled in your product. Please purchase it as a standalone for a low annual subscription or inside the Core+ bundle. <a target="_blank" href="https://time.ly/wordpress-calendar-plugin/addons/">Click here.</a></div>'
),
),
'default' => true,
),
'embedding' => array(
'type' => 'html',
'renderer' => array(
'class' => 'html',
'tab' => 'advanced',
'item' => 'embedded-views',
),
'default' => null,
),
'calendar_css_selector' => array(
'type' => 'deprecated',
'renderer' => array(
'class' => 'input',
'tab' => 'advanced',
'item' => 'advanced',
'label' => Ai1ec_I18n::__( 'Move calendar into this DOM element' ),
'type' => 'normal',
'help' => Ai1ec_I18n::__(
'Optional. Use this JavaScript-based shortcut to place the
calendar a DOM element other than the usual page content container
if you are unable to create an appropriate page template
for the calendar page. To use, enter a
<a target="_blank" href="https://api.jquery.com/category/selectors/">
jQuery selector</a> that evaluates to a single DOM element.
Any existing markup found within the target will be replaced
by the calendar.'
),
),
'default' => '',
),
'skip_in_the_loop_check' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'advanced',
'item' => 'advanced',
'label' => Ai1ec_I18n::__(
'<strong>Skip <tt>in_the_loop()</tt> check </strong> that protects against multiple calendar output'
),
'help' => Ai1ec_I18n::__(
'Try enabling this option if your calendar does not appear on the calendar page. It is needed for compatibility with a small number of themes that call <tt>the_content()</tt> from outside of The Loop. Leave disabled otherwise.'
),
),
'default' => false,
),
'disable_gzip_compression' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'advanced',
'item' => 'advanced',
'label' => Ai1ec_I18n::__(
'Disable <strong>gzip</strong> compression.'
),
'help' => Ai1ec_I18n::__(
'Use this option if calendar is unresponsive. <a target="_blank" href="https://time.ly/document/user-guide/troubleshooting/disable-gzip-compression/">Read more</a> about the issue. (From version 2.1 onwards, gzip is disabled by default for maximum compatibility.)'
),
),
'default' => true,
),
'ai1ec_use_frontend_rendering' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'advanced',
'item' => 'advanced',
'label' => Ai1ec_I18n::__(
'Use frontend rendering.'
),
'help' => Ai1ec_I18n::__(
'Renders calendar views on the client rather than the server; can improve performance.'
),
),
'default' => true,
),
'cache_dynamic_js' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'advanced',
'item' => 'advanced',
'label' => Ai1ec_I18n::__(
'Use advanced JS cache.'
),
'help' => Ai1ec_I18n::__(
'Cache dynamically generated JS files. Improves performance.'
),
),
'default' => true,
),
'render_css_as_link' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'advanced',
'item' => 'advanced',
'label' => Ai1ec_I18n::__(
'<strong>Link CSS</strong> in <code>&lt;head&gt;</code> section when file cache is unavailable.'
),
'help' => Ai1ec_I18n::__(
'Use this option if file cache is unavailable and you would prefer to serve CSS as a link rather than have it output inline.'
),
),
'default' => false,
),
'edit_robots_txt' => array(
'type' => 'string',
'renderer' => array(
'class' => 'textarea',
'tab' => 'advanced',
'item' => 'advanced',
'label' => Ai1ec_I18n::__( 'Current <strong>robots.txt</strong> on this site' ),
'type' => 'normal',
'rows' => 6,
'readonly' => 'readonly',
'help' => Ai1ec_I18n::__(
'The Robot Exclusion Standard, also known as the Robots Exclusion Protocol or
<code><a href="https://en.wikipedia.org/wiki/Robots.txt" target="_blank">robots.txt</a></code>
protocol, is a convention for cooperating web crawlers and other web robots
about accessing all or part of a website that is otherwise publicly viewable.
You can change it manually by editing <code>robots.txt</code> in your root WordPress directory.'
),
),
'default' => '',
),
'allow_statistics' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'advanced',
'item' => 'advanced',
'label' => sprintf(
Ai1ec_I18n::__(
'<strong>Publicize, promote, and share my events</strong> marked as public on the Timely network. (<a href="%s" target="_blank">Learn more &#187;</a>)'
),
'https://time.ly/event-search-calendar'
),
),
'default' => false,
),
'legacy_options' => array(
'type' => 'legacy_options',
'default' => null,
),
'ics_cron_freq' => array(
'type' => 'string',
'default' => 'hourly',
),
'twig_cache' => array(
'type' => 'string',
'renderer' => array(
'class' => 'cache',
'tab' => 'advanced',
'item' => 'cache',
'label' => sprintf(
Ai1ec_I18n::__(
'Templates cache improves site performance'
)
),
),
'default' => '',
),
'always_use_calendar_timezone' => array(
'type' => 'bool',
'renderer' => array(
'class' => 'checkbox',
'tab' => 'viewing-events',
'item' => 'viewing-events',
'label' => Ai1ec_I18n::__(
'Display events in <strong>calendar time zone</strong>'
),
'help' => Ai1ec_I18n::__(
'If this box is checked events will appear in the calendar time zone with time zone information displayed on the event details page.'
),
),
'default' => false,
),
);
}
/**
* Register the standard setting values.
*
* @return void Method doesn't return.
*/
protected function _register_standard_values() {
foreach ( $this->_standard_options as $key => $option ) {
$renderer = null;
$value = $option['default'];
if ( isset( $option['renderer'] ) ) {
$renderer = $option['renderer'];
}
$this->register(
$key,
$value,
$option['type'],
$renderer,
AI1EC_VERSION
);
}
}
/**
* Update translated strings, after introduction of `_noop` functions.
*
* @return void
*/
protected function _update_name_translations() {
$translations = $this->_standard_options['enabled_views']['default'];
$current = $this->get( 'enabled_views' );
foreach ( $current as $key => $view ) {
if ( isset( $translations[$key] ) ) {
$current[$key]['longname'] = $translations[$key]['longname'];
}
}
$this->set( 'enabled_views', $current );
}
/**
* Change `updated` flag value.
*
* @param bool $new_status Status to change to.
*
* @return bool Previous status flag value.
*/
protected function _change_update_status( $new_status ) {
$previous = $this->_updated;
$this->_updated = (bool)$new_status;
return $previous;
}
}