1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371: 372: 373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385: 386: 387: 388: 389: 390: 391: 392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405: 406: 407: 408: 409: 410: 411: 412: 413: 414: 415: 416: 417: 418: 419: 420: 421: 422: 423: 424: 
<?php

/**
 * This file allows you to manage the calendar.
 *
 * Simple Machines Forum (SMF)
 *
 * @package SMF
 * @author Simple Machines http://www.simplemachines.org
 * @copyright 2019 Simple Machines and individual contributors
 * @license http://www.simplemachines.org/about/smf/license.php BSD
 *
 * @version 2.1 RC1
 */

if (!defined('SMF'))
    die('No direct access...');

/**
 * The main controlling function doesn't have much to do... yet.
 * Just check permissions and delegate to the rest.
 *
 * uses ManageCalendar language file.
 */
function ManageCalendar()
{
    global $context, $txt, $modSettings;

    isAllowedTo('admin_forum');

    // Everything's gonna need this.
    loadLanguage('ManageCalendar');

    // Default text.
    $context['explain_text'] = $txt['calendar_desc'];

    // Little short on the ground of functions here... but things can and maybe will change...
    if (!empty($modSettings['cal_enabled']))
    {
        $subActions = array(
            'editholiday' => 'EditHoliday',
            'holidays' => 'ModifyHolidays',
            'settings' => 'ModifyCalendarSettings'
        );
        $default = 'holidays';
    }
    else
    {
        $subActions = array(
            'settings' => 'ModifyCalendarSettings'
        );
        $default = 'settings';
    }

    $_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : $default;

    // Set up the two tabs here...
    $context[$context['admin_menu_name']]['tab_data'] = array(
        'title' => $txt['manage_calendar'],
        'help' => 'calendar',
        'description' => $txt['calendar_settings_desc'],
    );
    if (!empty($modSettings['cal_enabled']))
        $context[$context['admin_menu_name']]['tab_data']['tabs'] = array(
            'holidays' => array(
                'description' => $txt['manage_holidays_desc'],
            ),
            'settings' => array(
                'description' => $txt['calendar_settings_desc'],
            ),
        );

    call_integration_hook('integrate_manage_calendar', array(&$subActions));

    call_helper($subActions[$_REQUEST['sa']]);
}

/**
 * The function that handles adding, and deleting holiday data
 */
function ModifyHolidays()
{
    global $sourcedir, $scripturl, $txt, $context, $modSettings;

    // Submitting something...
    if (isset($_REQUEST['delete']) && !empty($_REQUEST['holiday']))
    {
        checkSession();
        validateToken('admin-mc');

        foreach ($_REQUEST['holiday'] as $id => $value)
            $_REQUEST['holiday'][$id] = (int) $id;

        // Now the IDs are "safe" do the delete...
        require_once($sourcedir . '/Subs-Calendar.php');
        removeHolidays($_REQUEST['holiday']);
    }

    createToken('admin-mc');
    $listOptions = array(
        'id' => 'holiday_list',
        'title' => $txt['current_holidays'],
        'items_per_page' => $modSettings['defaultMaxListItems'],
        'base_href' => $scripturl . '?action=admin;area=managecalendar;sa=holidays',
        'default_sort_col' => 'name',
        'get_items' => array(
            'file' => $sourcedir . '/Subs-Calendar.php',
            'function' => 'list_getHolidays',
        ),
        'get_count' => array(
            'file' => $sourcedir . '/Subs-Calendar.php',
            'function' => 'list_getNumHolidays',
        ),
        'no_items_label' => $txt['holidays_no_entries'],
        'columns' => array(
            'name' => array(
                'header' => array(
                    'value' => $txt['holidays_title'],
                ),
                'data' => array(
                    'sprintf' => array(
                        'format' => '<a href="' . $scripturl . '?action=admin;area=managecalendar;sa=editholiday;holiday=%1$d">%2$s</a>',
                        'params' => array(
                            'id_holiday' => false,
                            'title' => false,
                        ),
                    ),
                ),
                'sort' => array(
                    'default' => 'title ASC, event_date ASC',
                    'reverse' => 'title DESC, event_date ASC',
                )
            ),
            'date' => array(
                'header' => array(
                    'value' => $txt['date'],
                ),
                'data' => array(
                    'function' => function($rowData) use ($txt)
                    {
                        // Recurring every year or just a single year?
                        $year = $rowData['year'] == '1004' ? sprintf('(%1$s)', $txt['every_year']) : $rowData['year'];

                        // Construct the date.
                        return sprintf('%1$d %2$s %3$s', $rowData['day'], $txt['months'][(int) $rowData['month']], $year);
                    },
                ),
                'sort' => array(
                    'default' => 'event_date',
                    'reverse' => 'event_date DESC',
                ),
            ),
            'check' => array(
                'header' => array(
                    'value' => '<input type="checkbox" onclick="invertAll(this, this.form);">',
                    'class' => 'centercol',
                ),
                'data' => array(
                    'sprintf' => array(
                        'format' => '<input type="checkbox" name="holiday[%1$d]">',
                        'params' => array(
                            'id_holiday' => false,
                        ),
                    ),
                    'class' => 'centercol',
                ),
            ),
        ),
        'form' => array(
            'href' => $scripturl . '?action=admin;area=managecalendar;sa=holidays',
            'token' => 'admin-mc',
        ),
        'additional_rows' => array(
            array(
                'position' => 'above_column_headers',
                'value' => '<input type="submit" name="delete" value="' . $txt['quickmod_delete_selected'] . '" class="button">
                    <a class="button" href="' . $scripturl . '?action=admin;area=managecalendar;sa=editholiday">' . $txt['holidays_add'] . '</a>',
            ),
            array(
                'position' => 'below_table_data',
                'value' => '<input type="submit" name="delete" value="' . $txt['quickmod_delete_selected'] . '" class="button">
                    <a class="button" href="' . $scripturl . '?action=admin;area=managecalendar;sa=editholiday">' . $txt['holidays_add'] . '</a>',
            ),
        ),
    );

    require_once($sourcedir . '/Subs-List.php');
    createList($listOptions);

    //loadTemplate('ManageCalendar');
    $context['page_title'] = $txt['manage_holidays'];

    // Since the list is the only thing to show, use the default list template.
    $context['default_list'] = 'holiday_list';
    $context['sub_template'] = 'show_list';
}

/**
 * This function is used for adding/editing a specific holiday
 */
function EditHoliday()
{
    global $txt, $context, $smcFunc;

    loadTemplate('ManageCalendar');

    $context['is_new'] = !isset($_REQUEST['holiday']);
    $context['page_title'] = $context['is_new'] ? $txt['holidays_add'] : $txt['holidays_edit'];
    $context['sub_template'] = 'edit_holiday';

    // Cast this for safety...
    if (isset($_REQUEST['holiday']))
        $_REQUEST['holiday'] = (int) $_REQUEST['holiday'];

    // Submitting?
    if (isset($_POST[$context['session_var']]) && (isset($_REQUEST['delete']) || $_REQUEST['title'] != ''))
    {
        checkSession();

        // Not too long good sir?
        $_REQUEST['title'] = $smcFunc['substr']($_REQUEST['title'], 0, 60);
        $_REQUEST['holiday'] = isset($_REQUEST['holiday']) ? (int) $_REQUEST['holiday'] : 0;

        if (isset($_REQUEST['delete']))
            $smcFunc['db_query']('', '
                DELETE FROM {db_prefix}calendar_holidays
                WHERE id_holiday = {int:selected_holiday}',
                array(
                    'selected_holiday' => $_REQUEST['holiday'],
                )
            );
        else
        {
            $date = strftime($_REQUEST['year'] <= 1004 ? '1004-%m-%d' : '%Y-%m-%d', mktime(0, 0, 0, $_REQUEST['month'], $_REQUEST['day'], $_REQUEST['year']));
            if (isset($_REQUEST['edit']))
                $smcFunc['db_query']('', '
                    UPDATE {db_prefix}calendar_holidays
                    SET event_date = {date:holiday_date}, title = {string:holiday_title}
                    WHERE id_holiday = {int:selected_holiday}',
                    array(
                        'holiday_date' => $date,
                        'selected_holiday' => $_REQUEST['holiday'],
                        'holiday_title' => $_REQUEST['title'],
                    )
                );
            else
                $smcFunc['db_insert']('',
                    '{db_prefix}calendar_holidays',
                    array(
                        'event_date' => 'date', 'title' => 'string-60',
                    ),
                    array(
                        $date, $_REQUEST['title'],
                    ),
                    array('id_holiday')
                );
        }

        updateSettings(array(
            'calendar_updated' => time(),
            'settings_updated' => time(),
        ));

        redirectexit('action=admin;area=managecalendar;sa=holidays');
    }

    // Default states...
    if ($context['is_new'])
        $context['holiday'] = array(
            'id' => 0,
            'day' => date('d'),
            'month' => date('m'),
            'year' => '0000',
            'title' => ''
        );
    // If it's not new load the data.
    else
    {
        $request = $smcFunc['db_query']('', '
            SELECT id_holiday, YEAR(event_date) AS year, MONTH(event_date) AS month, DAYOFMONTH(event_date) AS day, title
            FROM {db_prefix}calendar_holidays
            WHERE id_holiday = {int:selected_holiday}
            LIMIT 1',
            array(
                'selected_holiday' => $_REQUEST['holiday'],
            )
        );
        while ($row = $smcFunc['db_fetch_assoc']($request))
            $context['holiday'] = array(
                'id' => $row['id_holiday'],
                'day' => $row['day'],
                'month' => $row['month'],
                'year' => $row['year'] <= 4 ? 0 : $row['year'],
                'title' => $row['title']
            );
        $smcFunc['db_free_result']($request);
    }

    // Last day for the drop down?
    $context['holiday']['last_day'] = (int) strftime('%d', mktime(0, 0, 0, $context['holiday']['month'] == 12 ? 1 : $context['holiday']['month'] + 1, 0, $context['holiday']['month'] == 12 ? $context['holiday']['year'] + 1 : $context['holiday']['year']));
}

/**
 * Show and allow to modify calendar settings. Obviously.
 *
 * @param bool $return_config Whether to return the $config_vars array (used for admin search)
 * @return void|array Returns nothing or returns $config_vars if $return_config is true
 */
function ModifyCalendarSettings($return_config = false)
{
    global $context, $txt, $sourcedir, $scripturl, $smcFunc, $modSettings;

    // Load the boards list.
    $boards = array('');
    $request = $smcFunc['db_query']('order_by_board_order', '
        SELECT b.id_board, b.name AS board_name, c.name AS cat_name
        FROM {db_prefix}boards AS b
            LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)',
        array(
        )
    );
    while ($row = $smcFunc['db_fetch_assoc']($request))
        $boards[$row['id_board']] = $row['cat_name'] . ' - ' . $row['board_name'];
    $smcFunc['db_free_result']($request);

    require_once($sourcedir . '/Subs-Boards.php');
    sortBoards($boards);

    // Look, all the calendar settings - of which there are many!
    if (!empty($modSettings['cal_enabled']))
        $config_vars = array(
            array('check', 'cal_enabled'),
            '',

            // All the permissions:
            array('permissions', 'calendar_view'),
            array('permissions', 'calendar_post'),
            array('permissions', 'calendar_edit_own'),
            array('permissions', 'calendar_edit_any'),
            '',

            // How many days to show on board index, and where to display events etc?
            array('select', 'calendar_default_view', array('viewlist' => $txt['setting_cal_viewlist'], 'viewmonth' => $txt['setting_cal_viewmonth'], 'viewweek' => $txt['setting_cal_viewweek'])),
            array('int', 'cal_days_for_index', 'help' => 'cal_maxdays_advance', 6, 'postinput' => $txt['days_word']),
            array('select', 'cal_showholidays', array(0 => $txt['setting_cal_show_never'], 1 => $txt['setting_cal_show_cal'], 3 => $txt['setting_cal_show_index'], 2 => $txt['setting_cal_show_all'])),
            array('select', 'cal_showbdays', array(0 => $txt['setting_cal_show_never'], 1 => $txt['setting_cal_show_cal'], 3 => $txt['setting_cal_show_index'], 2 => $txt['setting_cal_show_all'])),
            array('select', 'cal_showevents', array(0 => $txt['setting_cal_show_never'], 1 => $txt['setting_cal_show_cal'], 3 => $txt['setting_cal_show_index'], 2 => $txt['setting_cal_show_all'])),
            array('check', 'cal_export'),
            '',

            // Linking events etc...
            array('select', 'cal_defaultboard', $boards),
            array('check', 'cal_daysaslink', 'help' => 'cal_link_postevent'),
            array('check', 'cal_allow_unlinked', 'help' => 'cal_allow_unlinkedevents'),
            array('check', 'cal_showInTopic'),
            '',

            // Dates of calendar...
            array('int', 'cal_minyear', 'help' => 'cal_min_year'),
            array('int', 'cal_maxyear', 'help' => 'cal_max_year'),
            '',

            // Calendar spanning...
            array('int', 'cal_maxspan', 6, 'postinput' => $txt['days_word'], 'subtext' => $txt['zero_for_no_limit'], 'help' => 'cal_maxevent_span'),
            '',

            // A comment is like a dog marking its territory. ;)
            array('select', 'cal_highlight_events', array(0 => $txt['setting_cal_highlight_none'], 1 => $txt['setting_cal_highlight_mini'], 2 => $txt['setting_cal_highlight_main'], 3 => $txt['setting_cal_highlight_both'])),
            array('select', 'cal_highlight_holidays', array(0 => $txt['setting_cal_highlight_none'], 1 => $txt['setting_cal_highlight_mini'], 2 => $txt['setting_cal_highlight_main'], 3 => $txt['setting_cal_highlight_both'])),
            array('select', 'cal_highlight_birthdays', array(0 => $txt['setting_cal_highlight_none'], 1 => $txt['setting_cal_highlight_mini'], 2 => $txt['setting_cal_highlight_main'], 3 => $txt['setting_cal_highlight_both'])),
            '',

            // Miscellaneous layout settings...
            array('check', 'cal_disable_prev_next'),
            array('select', 'cal_display_type', array(0 => $txt['setting_cal_display_comfortable'], 1 => $txt['setting_cal_display_compact'])),
            array('select', 'cal_week_links', array(0 => $txt['setting_cal_week_links_none'], 1 => $txt['setting_cal_week_links_mini'], 2 => $txt['setting_cal_week_links_main'], 3 => $txt['setting_cal_week_links_both'])),
            array('check', 'cal_prev_next_links'),
            array('check', 'cal_short_days'),
            array('check', 'cal_short_months'),
        );
    else
        $config_vars = array(
            array('check', 'cal_enabled'),
        );

    call_integration_hook('integrate_modify_calendar_settings', array(&$config_vars));
    if ($return_config)
        return $config_vars;

    // Get the settings template fired up.
    require_once($sourcedir . '/ManageServer.php');

    // Some important context stuff
    $context['page_title'] = $txt['calendar_settings'];
    $context['sub_template'] = 'show_settings';

    // Get the final touches in place.
    $context['post_url'] = $scripturl . '?action=admin;area=managecalendar;save;sa=settings';
    $context['settings_title'] = $txt['calendar_settings'];

    // Saving the settings?
    if (isset($_GET['save']))
    {
        checkSession();
        call_integration_hook('integrate_save_calendar_settings');
        saveDBSettings($config_vars);

        // Update the stats in case.
        updateSettings(array(
            'calendar_updated' => time(),
        ));

        $_SESSION['adm-save'] = true;
        redirectexit('action=admin;area=managecalendar;sa=settings');
    }

    // We need this for the inline permissions
    createToken('admin-mp');

    // Prepare the settings...
    prepareDBSettingContext($config_vars);
}

?>