Example #1
0
/**
 * Counts the number of rows in a table.
 *
 * @param array $atts
 * @param string $atts['table'] MySQL table name.
 * @param string $atts['where'] MySQL WHERE clause.
 */
function jmd_count($atts)
{
    extract(lAtts(array('table' => '', 'where' => ''), $atts));
    if ($where != '') {
        $where = ' where ' . $where;
    }
    return getThing("select count(*) from " . safe_pfx($table) . " {$where}");
}
Example #2
0
function jmd_admin_js()
{
    global $event;
    if ($rs = getRows('select name, js from ' . safe_pfx('txp_js'))) {
        foreach ($rs as $row) {
            if ($row['name'] === 'default' || $row['name'] === $event) {
                $out[] = base64_decode($row['js']);
            }
        }
        echo tag(join("\n", $out), 'script', ' type="text/javascript"');
    }
}
function cnk_ver_do_deinstall()
{
    $sql = "ALTER TABLE " . safe_pfx('txp_form') . " DROP `file_mod_time`;ALTER TABLE " . safe_pfx('txp_page') . " DROP `file_mod_time`;ALTER TABLE " . safe_pfx('txp_css') . " DROP `file_mod_time`;";
    if (!cnk_ver_batch_query($sql)) {
        return false;
    } else {
        return true;
    }
}
 private function getEntry()
 {
     $row = getRow("SELECT last_mod, contents FROM " . safe_pfx('jmd_wiki_events') . " WHERE title = '{$this->day}'");
     if ($row) {
         $diff = str_replace('-', '', $this->currentDate) - str_replace('-', '', $row['last_mod']);
         // if the content is at least two months old, update
         if ($diff > 200) {
             return $this->setEntry($update = 1);
         } else {
             return $row['contents'];
         }
     }
 }
Example #5
0
function sec_section_list($message = '')
{
    global $event, $section_list_pageby;
    pagetop(gTxt('tab_sections'), $message);
    extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method')));
    if ($sort === '') {
        $sort = get_pref('section_sort_column', 'time');
    }
    if ($dir === '') {
        $dir = get_pref('section_sort_dir', 'desc');
    }
    $dir = $dir == 'asc' ? 'asc' : 'desc';
    switch ($sort) {
        case 'title':
            $sort_sql = 'title ' . $dir;
            break;
        case 'page':
            $sort_sql = 'page ' . $dir;
            break;
        case 'css':
            $sort_sql = 'css ' . $dir;
            break;
        case 'in_rss':
            $sort_sql = 'in_rss ' . $dir;
            break;
        case 'on_frontpage':
            $sort_sql = 'on_frontpage ' . $dir;
            break;
        case 'searchable':
            $sort_sql = 'searchable ' . $dir;
            break;
        case 'article_count':
            $sort_sql = 'article_count ' . $dir;
            break;
        default:
            $sort_sql = 'name ' . $dir;
            break;
    }
    set_pref('section_sort_column', $sort, 'section', 2, '', 0, PREF_PRIVATE);
    set_pref('section_sort_dir', $dir, 'section', 2, '', 0, PREF_PRIVATE);
    $switch_dir = $dir == 'desc' ? 'asc' : 'desc';
    $criteria = 1;
    if ($search_method and $crit != '') {
        $verbatim = preg_match('/^"(.*)"$/', $crit, $m);
        $crit_escaped = doSlash($verbatim ? $m[1] : str_replace(array('\\', '%', '_', '\''), array('\\\\', '\\%', '\\_', '\\\''), $crit));
        $critsql = $verbatim ? array('name' => "name = '{$crit_escaped}'", 'title' => "title = '{$crit_escaped}'", 'page' => "page = '{$crit_escaped}'", 'css' => "css = '{$crit_escaped}'", 'in_rss' => "in_rss = '{$crit_escaped}'", 'on_frontpage' => "on_frontpage = '{$crit_escaped}'", 'searchable' => "searchable = '{$crit_escaped}'") : array('name' => "name like '%{$crit_escaped}%'", 'title' => "title like '%{$crit_escaped}%'", 'page' => "page like '%{$crit_escaped}%'", 'css' => "css like '%{$crit_escaped}%'", 'in_rss' => "in_rss = '{$crit_escaped}'", 'on_frontpage' => "on_frontpage = '{$crit_escaped}'", 'searchable' => "searchable = '{$crit_escaped}'");
        if (array_key_exists($search_method, $critsql)) {
            $criteria = $critsql[$search_method];
            $limit = 500;
        } else {
            $search_method = '';
            $crit = '';
        }
    } else {
        $search_method = '';
        $crit = '';
    }
    $criteria .= callback_event('admin_criteria', 'section_list', 0, $criteria);
    $total = safe_count('txp_section', "{$criteria}");
    echo '<h1 class="txp-heading">' . gTxt('tab_sections') . sp . popHelp('section_category') . '</h1>';
    echo '<div id="' . $event . '_control" class="txp-control-panel">';
    echo graf(sLink('section', 'section_edit', gTxt('create_section')), ' class="txp-buttons"');
    echo n . '<form id="default_section_form" name="default_section_form" method="post" action="index.php" class="async">';
    echo graf('<label>' . gTxt('default_write_section') . '</label>' . sp . popHelp('section_default') . n . section_select_list()) . eInput('section') . sInput('section_set_default');
    echo '</form>';
    if ($total < 1) {
        if ($criteria != 1) {
            echo n . section_search_form($crit, $search_method) . n . graf(gTxt('no_results_found'), ' class="indicator"') . '</div>';
        }
        return;
    }
    $limit = max($section_list_pageby, 15);
    list($page, $offset, $numPages) = pager($total, $limit, $page);
    echo n . section_search_form($crit, $search_method) . '</div>';
    $rs = safe_rows_start('*, (SELECT count(*) FROM ' . safe_pfx('textpattern') . ' articles WHERE articles.Section = txp_section.name) AS article_count', 'txp_section', "{$criteria} order by {$sort_sql} limit {$offset}, {$limit}");
    if ($rs) {
        echo n . '<div id="' . $event . '_container" class="txp-container">';
        echo n . n . '<form action="index.php" id="section_form" class="multi_edit_form" method="post" name="longform">' . n . '<div class="txp-listtables">' . n . n . startTable('', '', 'txp-list') . n . '<thead>' . n . tr(n . hCell(fInput('checkbox', 'select_all', 0, '', '', '', '', '', 'select_all'), '', ' title="' . gTxt('toggle_all_selected') . '" class="multi-edit"') . n . column_head('name', 'name', 'section', true, $switch_dir, $crit, $search_method, ('name' == $sort ? "{$dir} " : '') . 'name') . n . column_head('title', 'title', 'section', true, $switch_dir, $crit, $search_method, ('title' == $sort ? "{$dir} " : '') . 'title') . n . column_head('page', 'page', 'section', true, $switch_dir, $crit, $search_method, ('page' == $sort ? "{$dir} " : '') . 'page') . n . column_head('css', 'css', 'section', true, $switch_dir, $crit, $search_method, ('css' == $sort ? "{$dir} " : '') . 'style') . n . column_head('on_front_page', 'on_frontpage', 'section', true, $switch_dir, $crit, $search_method, ('on_frontpage' == $sort ? "{$dir} " : '') . 'section_detail frontpage') . n . column_head('syndicate', 'in_rss', 'section', true, $switch_dir, $crit, $search_method, ('in_rss' == $sort ? "{$dir} " : '') . 'section_detail syndicate') . n . column_head('include_in_search', 'searchable', 'section', true, $switch_dir, $crit, $search_method, ('searchable' == $sort ? "{$dir} " : '') . 'section_detail searchable') . n . column_head('articles', 'article_count', 'section', true, $switch_dir, $crit, $search_method, ('article_count' == $sort ? "{$dir} " : '') . 'section_detail article_count')) . n . '</thead>';
        echo '<tbody>';
        while ($a = nextRow($rs)) {
            extract($a, EXTR_PREFIX_ALL, 'sec');
            $is_default_section = $sec_name == 'default';
            $edit_url = '?event=section' . a . 'step=section_edit' . a . 'name=' . $sec_name . a . 'sort=' . $sort . a . 'dir=' . $dir . a . 'page=' . $page . a . 'search_method=' . $search_method . a . 'crit=' . $crit;
            $page_url = '?event=page' . a . 'name=' . $sec_page;
            $style_url = '?event=css' . a . 'name=' . $sec_css;
            $articles = $sec_article_count > 0 ? href($sec_article_count, '?event=list' . a . 'search_method=section' . a . 'crit=&quot;' . txpspecialchars($sec_name) . '&quot;', ' title="' . gTxt('article_count', array('{num}' => $sec_article_count)) . '"') : ($is_default_section ? '' : '0');
            //				$can_delete = ($sec_name != 'default' && $sec_article_count == 0);
            $parms = array('step' => 'section_toggle_option', 'thing' => $sec_name);
            echo tr(td(fInput('checkbox', 'selected[]', $sec_name), '', 'multi-edit') . td('<a href="' . $edit_url . '" title="' . gTxt('edit') . '">' . $sec_name . '</a>' . n . '<span class="section_detail">[<a href="' . hu . $sec_name . '">' . gTxt('view') . '</a>]</span>', '', 'name') . td(txpspecialchars($sec_title), '', 'title') . td('<a href="' . $page_url . '" title="' . gTxt('edit') . '">' . $sec_page . '</a>', '', 'page') . td('<a href="' . $style_url . '" title="' . gTxt('edit') . '">' . $sec_css . '</a>', '', 'style') . td($is_default_section ? '-' : asyncHref($sec_on_frontpage ? gTxt('yes') : gTxt('no'), $parms + array('property' => 'on_frontpage')), '', 'section_detail frontpage') . td($is_default_section ? '-' : asyncHref($sec_in_rss ? gTxt('yes') : gTxt('no'), $parms + array('property' => 'in_rss')), '', 'section_detail syndicate') . td($is_default_section ? '-' : asyncHref($sec_searchable ? gTxt('yes') : gTxt('no'), $parms + array('property' => 'searchable')), '', 'section_detail searchable') . td($is_default_section ? '' : $articles, '', 'section_detail article_count'), ' id="txp_section_' . $sec_name . '"');
        }
        echo '</tbody>', n, endTable(), n, '</div>', n, section_multiedit_form($page, $sort, $dir, $crit, $search_method), n, tInput(), n, '</form>', n, graf(toggle_box('section_detail'), ' class="detail-toggle"'), n, '<div id="' . $event . '_navigation" class="txp-navigation">', n, nav_form('section', $page, $numPages, $sort, $dir, $crit, $search_method, $total, $limit), n, pageby_form('section', $section_list_pageby), n, '</div>', n, '</div>';
        echo script_js(<<<EOS
\t\t\t\$('#default_section').change(function() {
\t\t\t\t\$('#default_section_form').submit();
\t\t\t});
EOS
);
    }
}
Example #6
0
/**
 * Renders the list of preferences.
 *
 * Plugins may add their own prefs, for example by using plugin lifecycle events or
 * raising a (pre) callback on event=admin / step=prefs_list so they are installed
 * or updated when accessing the Preferences panel. Access to the prefs can be
 * controlled by using add_privs() on 'prefs.your-prefs-event-name'.
 *
 * @param  string $message The feedback / error string to display
 */
function prefs_list($message = '')
{
    global $prefs, $txp_user;
    extract($prefs);
    pagetop(gTxt('tab_preferences'), $message);
    $locale = setlocale(LC_ALL, $locale);
    echo hed(gTxt('tab_preferences'), 1, array('class' => 'txp-heading'));
    echo n . '<div id="prefs_container" class="txp-container">' . n . '<form method="post" class="prefs-form" action="index.php">' . n . '<div class="txp-layout-textbox">';
    // TODO: remove 'custom' when custom fields are refactored.
    $core_events = array('site', 'admin', 'publish', 'feeds', 'comments', 'custom');
    $joined_core = join(',', quote_list($core_events));
    $sql = array();
    $sql[] = 'prefs_id = 1 and event != "" and type in(' . PREF_CORE . ', ' . PREF_PLUGIN . ')';
    $sql[] = "(user_name = '' or (user_name='" . doSlash($txp_user) . "' and name not in(\n            select name from " . safe_pfx('txp_prefs') . " where user_name = ''\n        )))";
    if (!get_pref('use_comments', 1, 1)) {
        $sql[] = "event != 'comments'";
    }
    $rs = safe_rows_start("*, FIELD(event,{$joined_core}) as sort_value", 'txp_prefs', join(' and ', $sql) . " ORDER BY sort_value = 0, sort_value, event, position");
    $last_event = null;
    $out = array();
    if (numRows($rs)) {
        while ($a = nextRow($rs)) {
            if (!has_privs('prefs.' . $a['event'])) {
                continue;
            }
            if ($a['event'] !== $last_event) {
                if ($last_event !== null) {
                    echo wrapRegion('prefs_group_' . $last_event, join(n, $out), 'prefs_' . $last_event, $last_event, 'prefs_' . $last_event);
                }
                $last_event = $a['event'];
                $out = array();
            }
            $label = '';
            if (!in_array($a['html'], array('yesnoradio', 'is_dst'))) {
                $label = $a['name'];
            }
            // TODO: remove exception when custom fields move to meta store.
            $help = '';
            if (strpos($a['name'], 'custom_') === false) {
                $help = $a['name'];
            }
            if ($a['html'] == 'text_input') {
                $size = INPUT_REGULAR;
            } else {
                $size = '';
            }
            $out[] = inputLabel($a['name'], pref_func($a['html'], $a['name'], $a['val'], $size), $label, $help, array('id' => 'prefs-' . $a['name']));
        }
    }
    if ($last_event === null) {
        echo graf(gTxt('no_preferences'));
    } else {
        echo wrapRegion('prefs_group_' . $last_event, join(n, $out), 'prefs_' . $last_event, $last_event, 'prefs_' . $last_event);
    }
    echo n . '</div>' . sInput('prefs_save') . eInput('prefs') . hInput('prefs_id', '1') . tInput();
    if ($last_event !== null) {
        echo graf(fInput('submit', 'Submit', gTxt('save'), 'publish'));
    }
    echo n . '</form>' . n . '</div>';
}
Example #7
0
/**
 * Renders the list of preferences.
 *
 * Plugins may add their own prefs, for example by using plugin lifecycle events
 * or raising a (pre) callback on event=admin / step=prefs_list so they are
 * installed or updated when accessing the Preferences panel. Access to the
 * prefs can be controlled by using add_privs() on 'prefs.your-prefs-event-name'.
 *
 * @param string $message The feedback / error string to display
 */
function prefs_list($message = '')
{
    global $prefs, $txp_user;
    extract($prefs);
    pagetop(gTxt('tab_preferences'), $message);
    $locale = setlocale(LC_ALL, $locale);
    echo n . '<form class="prefs-form" id="prefs_form" method="post" action="index.php">';
    // TODO: remove 'custom' when custom fields are refactored.
    $core_events = array('site', 'admin', 'publish', 'feeds', 'comments', 'custom');
    $joined_core = join(',', quote_list($core_events));
    $sql = array();
    $sql[] = 'prefs_id = 1 and event != "" and type in(' . PREF_CORE . ', ' . PREF_PLUGIN . ')';
    $sql[] = "(user_name = '' OR (user_name = '" . doSlash($txp_user) . "' AND name NOT IN (\n            SELECT name FROM " . safe_pfx('txp_prefs') . " WHERE user_name = ''\n        )))";
    if (!get_pref('use_comments', 1, 1)) {
        $sql[] = "event != 'comments'";
    }
    $rs = safe_rows_start("*, FIELD(event, {$joined_core}) AS sort_value", 'txp_prefs', join(" AND ", $sql) . " ORDER BY sort_value = 0, sort_value, event, position");
    $last_event = null;
    $out = array();
    $build = array();
    $groupOut = array();
    if (numRows($rs)) {
        while ($a = nextRow($rs)) {
            if (!has_privs('prefs.' . $a['event'])) {
                continue;
            }
            if ($a['event'] !== $last_event) {
                if ($last_event !== null) {
                    $build[] = tag(hed(gTxt($last_event), 2, array('id' => 'prefs_group_' . $last_event . '-label')) . join(n, $out), 'section', array('class' => 'txp-prefs-group', 'id' => 'prefs_group_' . $last_event, 'aria-labelledby' => 'prefs_group_' . $last_event . '-label'));
                    $groupOut[] = n . tag(href(gTxt($last_event), '#prefs_group_' . $last_event, array('data-txp-pane' => $last_event, 'data-txp-token' => form_token())), 'li');
                }
                $last_event = $a['event'];
                $out = array();
            }
            $label = '';
            if (!in_array($a['html'], array('yesnoradio', 'is_dst'))) {
                $label = $a['name'];
            }
            // TODO: remove exception when custom fields move to meta store.
            $help = '';
            if (strpos($a['name'], 'custom_') === false) {
                $help = $a['name'];
            }
            if ($a['html'] == 'text_input') {
                $size = INPUT_REGULAR;
            } else {
                $size = '';
            }
            $out[] = inputLabel($a['name'], pref_func($a['html'], $a['name'], $a['val'], $size), $label, $help, array('class' => 'txp-form-field', 'id' => 'prefs-' . $a['name']));
        }
    }
    if ($last_event === null) {
        echo graf(gTxt('no_preferences'));
    } else {
        $build[] = tag(hed(gTxt($last_event), 2, array('id' => 'prefs_group_' . $last_event . '-label')) . join(n, $out), 'section', array('class' => 'txp-prefs-group', 'id' => 'prefs_group_' . $last_event, 'aria-labelledby' => 'prefs_group_' . $last_event . '-label'));
        $groupOut[] = n . tag(href(gTxt($last_event), '#prefs_group_' . $last_event, array('data-txp-pane' => $last_event, 'data-txp-token' => form_token())), 'li') . n;
        echo hed(gTxt('tab_preferences'), 1, array('class' => 'txp-heading')) . n . '<div class="txp-layout-4col-cell-1alt">' . wrapGroup('all_preferences', n . tag(join($groupOut), 'ul', array('class' => 'switcher-list')), 'all_preferences');
        if ($last_event !== null) {
            echo graf(fInput('submit', 'Submit', gTxt('save'), 'publish'), array('class' => 'txp-save'));
        }
        echo n . '</div>' . n . '<div class="txp-layout-4col-cell-2-3-4">' . join(n, $build) . n . '</div>' . sInput('prefs_save') . eInput('prefs') . hInput('prefs_id', '1') . tInput();
    }
    echo n . '</form>';
}
Example #8
0
/**
 * Processes delete actions sent using the multi-edit form.
 */
function section_delete()
{
    $selectedList = ps('selected');
    $selected = join(',', quote_list($selectedList));
    $message = '';
    $sections = safe_column('name', 'txp_section', "name != 'default' and name in ({$selected}) and name not in (select Section from " . safe_pfx('textpattern') . ")");
    $sectionsNotDeleted = array_diff($selectedList, $sections);
    if ($sections && safe_delete('txp_section', 'name in (' . join(',', quote_list($sections)) . ')')) {
        callback_event('sections_deleted', '', 0, $sections);
        $message = gTxt('section_deleted', array('{name}' => join(', ', $sections)));
    }
    if ($sectionsNotDeleted) {
        $severity = $message ? E_WARNING : E_ERROR;
        $message = array(($message ? $message . n : '') . gTxt('section_delete_failure', array('{name}' => join(', ', $sectionsNotDeleted))), $severity);
    }
    sec_section_list($message);
}
Example #9
0
function getNeighbour($Posted, $s, $type)
{
    global $prefs;
    extract($prefs);
    $expired = $publish_expired_articles ? '' : ' and (now() <= Expires or Expires = ' . NULLDATETIME . ')';
    $type = $type == '>' ? '>' : '<';
    $safe_name = safe_pfx('textpattern');
    $q = array("select ID, Title, url_title, unix_timestamp(Posted) as uposted\n\t\t\tfrom " . $safe_name . " where Posted {$type} '" . doSlash($Posted) . "'", $s != '' && $s != 'default' ? "and Section = '" . doSlash($s) . "'" : filterFrontPage(), 'and Status=4 and Posted < now()' . $expired . ' order by Posted', $type == '<' ? 'desc' : 'asc', 'limit 1');
    $out = getRow(join(' ', $q));
    return is_array($out) ? $out : '';
}
Example #10
0
/**
 * Sends a password reset link to a user's email address.
 *
 * This function will return a success message even when the specified user
 * doesn't exist. Though an error message could be thrown when a user isn't
 * found, this is done due to security, which prevents the function from
 * leaking existing account names.
 *
 * @param  string $name The login name
 * @return string A localized message string
 * @see    send_new_password()
 * @see    reset_author_pass()
 * @example
 * echo send_reset_confirmation_request('username');
 */
function send_reset_confirmation_request($name)
{
    global $sitename;
    $expiryTimestamp = time() + 60 * RESET_EXPIRY_MINUTES;
    $expiry = strftime('%Y-%m-%d %H:%M:%S', $expiryTimestamp);
    $rs = safe_query("SELECT\n            txp_users.user_id, txp_users.email,\n            txp_users.nonce, txp_users.pass,\n            txp_token.type\n        FROM " . safe_pfx('txp_users') . " txp_users\n        LEFT JOIN " . safe_pfx('txp_token') . " txp_token\n        ON txp_users.user_id = txp_token.reference_id\n        WHERE txp_users.name = '" . doSlash($name) . "'\n        AND TIMESTAMPDIFF(SECOND, txp_token.expires, '" . $expiry . "') > " . 60 * RESET_RATE_LIMIT_MINUTES . "\n        AND txp_token.type = 'password_reset'");
    $row = nextRow($rs);
    if ($row) {
        extract($row);
        $uid = assert_int($user_id);
        // The selector becomes an indirect reference to the txp_users row,
        // which does not leak information.
        $selector = Txp::get('\\Textpattern\\Password\\Random')->generate(12);
        $expiryYear = safe_strftime('%Y', $expiryTimestamp);
        $expiryMonth = safe_strftime('%B', $expiryTimestamp);
        $expiryDay = safe_strftime('%Oe', $expiryTimestamp);
        $expiryTime = safe_strftime('%H:%M', $expiryTimestamp);
        // Use a hash of the nonce, selector and password.
        // This ensures that confirmation requests expire automatically when:
        //  a) The person next logs in, or
        //  b) They successfully change their password (usually as a result of this reset request)
        // Using the selector in the hash just injects randomness, otherwise two requests
        // back-to-back would generate the same confirmation code.
        // Old requests for the same user id are purged every time a new request is made.
        $token = bin2hex(pack('H*', substr(hash(HASHING_ALGORITHM, $nonce . $selector . $pass), 0, SALT_LENGTH)));
        $confirm = $token . $selector;
        // Remove any previous reset tokens and insert the new one.
        safe_delete("txp_token", "reference_id = {$uid} AND type = 'password_reset'");
        safe_insert("txp_token", "reference_id = {$uid},\n                type = 'password_reset',\n                selector = '" . doSlash($selector) . "',\n                token = '" . doSlash($token) . "',\n                expires = '" . doSlash($expiry) . "'\n            ");
        $message = gTxt('salutation', array('{name}' => $name)) . n . n . gTxt('password_reset_confirmation') . n . hu . 'textpattern/index.php?confirm=' . $confirm . n . n . gTxt('link_expires', array('{year}' => $expiryYear, '{month}' => $expiryMonth, '{day}' => $expiryDay, '{time}' => $expiryTime));
        if (txpMail($email, "[{$sitename}] " . gTxt('password_reset_confirmation_request'), $message)) {
            return gTxt('password_reset_confirmation_request_sent');
        } else {
            return array(gTxt('could_not_mail'), E_ERROR);
        }
    } else {
        // Though 'unknown_author' could be thrown, send generic 'request_sent'
        // message instead so that (non-)existence of account names are not leaked.
        // Since this is a short circuit, there's a possibility of a timing attack
        // revealing the existence of an account, which we could defend against
        // to some degree.
        return gTxt('password_reset_confirmation_request_sent');
    }
}
function _sed_cp_safe_pfx($table)
{
    if (is_callable('safe_pfx')) {
        $table = safe_pfx($table);
    } else {
        $table = PFX . $table;
    }
    return $table;
}
/**
	Installer
	@param $event string Admin-side event.
	@param $step string Admin-side event, plugin-lifecycle step.
*/
function rah_textile_bar_install($event = '', $step = '')
{
    if ($step == 'deleted') {
        safe_delete('txp_prefs', "name like 'rah_textile_bar_%'");
        return;
    }
    global $prefs, $event, $textarray;
    if ($event == 'prefs') {
        /*
        	Generate language strings if
        	not existing
        */
        $strings = array('rah_txtbar' => 'Textile Bar', 'rah_textile_bar_body' => 'Attach to Body field', 'rah_textile_bar_excerpt' => 'Attach to Excerpt field');
        foreach (rah_textile_bar_buttons() as $att) {
            $strings['rah_textile_bar_' . $att[0]] = 'Show ' . $att[0];
        }
        foreach ($strings as $string => $translation) {
            if (!isset($textarray[$string])) {
                $textarray[$string] = $translation;
            }
        }
    }
    $version = '0.7';
    $current = isset($prefs['rah_textile_bar_version']) ? $prefs['rah_textile_bar_version'] : '';
    if ($current == $version) {
        return;
    }
    $default = array('disable' => '', 'fields' => '');
    if (!$current) {
        /*
        	Run migration and clean-up if older version was
        	installed
        */
        @($rs = safe_rows('name, value', 'rah_textile_bar', '1=1'));
        if (!empty($rs) && is_array($rs)) {
            foreach ($rs as $a) {
                if (isset($default[$a['name']])) {
                    $default[$a['name']] = $a['value'];
                }
            }
            @safe_query('DROP TABLE IF EXISTS ' . safe_pfx('rah_textile_bar'));
        }
    }
    /*
    	Add preference strings
    */
    $disabled = explode(',', $default['disable']);
    $position = 230;
    $values = rah_textile_bar_buttons();
    foreach (array('body', 'excerpt') as $val) {
        $values[] = array($val);
    }
    foreach ($values as $att) {
        $val = $att[0] == 'body' || $att[0] == 'excerpt' ? strpos($default['fields'], $att[0]) !== false || !$default['fields'] ? 1 : 0 : (in_array('#textilebar .' . $att[0], $disabled) ? 0 : 1);
        if ($att[0] == 'body' || $att[0] == 'excerpt') {
            $position = 225;
        }
        $name = 'rah_textile_bar_' . $att[0];
        if (!isset($prefs[$name])) {
            safe_insert('txp_prefs', "prefs_id=1,\n\t\t\t\t\tname='" . doSlash($name) . "',\n\t\t\t\t\tval='" . doSlash($val) . "',\n\t\t\t\t\ttype=1,\n\t\t\t\t\tevent='rah_txtbar',\n\t\t\t\t\thtml='yesnoradio',\n\t\t\t\t\tposition=" . $position);
            $prefs[$name] = $val;
        }
        $position++;
    }
    set_pref('rah_textile_bar_version', $version, 'rah_txtbar', 2, '', 0);
    $prefs['rah_textile_bar_version'] = $version;
}
Example #13
0
function recent_comments($atts)
{
    extract(lAtts(array('break' => br, 'class' => __FUNCTION__, 'label' => '', 'labeltag' => '', 'limit' => 10, 'sort' => 'posted desc', 'wraptag' => ''), $atts));
    $sort = preg_replace('/\\bposted\\b/', 'd.posted', $sort);
    $rs = startRows('select d.name, d.discussid, t.ID as thisid, unix_timestamp(t.Posted) as posted, t.Title as title, t.Section as section, t.url_title ' . 'from ' . safe_pfx('txp_discuss') . ' as d inner join ' . safe_pfx('textpattern') . ' as t on d.parentid = t.ID ' . 'where t.Status >= 4 and d.visible = ' . VISIBLE . ' order by ' . doSlash($sort) . ' limit 0,' . intval($limit));
    if ($rs) {
        $out = array();
        while ($c = nextRow($rs)) {
            $out[] = href($c['name'] . ' (' . escape_title($c['title']) . ')', permlinkurl($c) . '#c' . $c['discussid']);
        }
        if ($out) {
            return doLabel($label, $labeltag) . doWrap($out, $wraptag, $break, $class);
        }
    }
    return '';
}
function cat_event_category_list($event)
{
    $rs = getTree('root', $event);
    $parent = ps('parent_cat');
    $heading = 'tab_' . ($event == 'article' ? 'list' : $event);
    $for = $rs ? ' for="' . $event . '_category_parent"' : '';
    $out = n . n . hed(gTxt($heading) . sp . popHelp($event . '_category'), 2) . form(fInput('text', 'title', '', '', '', '', INPUT_REGULAR) . ($rs ? '<div class="parent"><label' . $for . '>' . gTxt('parent') . '</label>' . treeSelectInput('parent_cat', $rs, $parent, $event . '_category_parent') . '</div>' : '') . n . fInput('submit', '', gTxt('Create')) . n . eInput('category') . n . sInput('cat_' . $event . '_create'), '', '', 'post', 'action-create ' . $event);
    if ($rs) {
        $total_count = array();
        if ($event == 'article') {
            // Count distinct articles for both categories, avoid duplicates
            $rs2 = getRows('select category, count(*) as num from (' . 'select ID, Category1 as category from ' . safe_pfx('textpattern') . ' union ' . 'select ID, Category2 as category from ' . safe_pfx('textpattern') . ') as t where category != "" group by category');
            if ($rs2 !== false) {
                foreach ($rs2 as $a) {
                    $total_count[$a['category']] = $a['num'];
                }
            }
        } else {
            switch ($event) {
                case 'link':
                    $rs2 = safe_rows_start('category, count(*) as num', 'txp_link', "1 group by category");
                    break;
                case 'image':
                    $rs2 = safe_rows_start('category, count(*) as num', 'txp_image', "1 group by category");
                    break;
                case 'file':
                    $rs2 = safe_rows_start('category, count(*) as num', 'txp_file', "1 group by category");
                    break;
            }
            while ($a = nextRow($rs2)) {
                $name = $a['category'];
                $num = $a['num'];
                $total_count[$name] = $num;
            }
        }
        $items = array();
        foreach ($rs as $a) {
            extract($a);
            // format count
            switch ($event) {
                case 'article':
                    $url = 'index.php?event=list' . a . 'search_method=categories' . a . 'crit=' . $name;
                    break;
                case 'link':
                    $url = 'index.php?event=link' . a . 'search_method=category' . a . 'crit=' . $name;
                    break;
                case 'image':
                    $url = 'index.php?event=image' . a . 'search_method=category' . a . 'crit=' . $name;
                    break;
                case 'file':
                    $url = 'index.php?event=file' . a . 'search_method=category' . a . 'crit=' . $name;
                    break;
            }
            $count = isset($total_count[$name]) ? href('(' . $total_count[$name] . ')', $url) : '(0)';
            if (empty($title)) {
                $edit_link = '<em>' . eLink('category', 'cat_' . $event . '_edit', 'id', $id, gTxt('untitled')) . '</em>';
            } else {
                $edit_link = eLink('category', 'cat_' . $event . '_edit', 'id', $id, $title);
            }
            $items[] = graf(checkbox('selected[]', $id, 0) . sp . str_repeat(sp . sp, $level * 2) . $edit_link . sp . $count, ' class="level-' . $level . '"');
        }
        if ($items) {
            $out .= cat_article_multiedit_form($event, $items);
        }
    } else {
        $out .= graf(gTxt('no_categories_exist'));
    }
    return $out;
}
Example #15
0
 /** Run the query.
  *  Runs an UPDATE query if $where is set, otherwise INSERT
  *  @return bool success or failure
  */
 public function upsert()
 {
     $this->init_query();
     if (count($this->where)) {
         return safe_upsert($this->table, $this->set_clause, $this->clause_string());
     }
     if ($this->set_clause) {
         return safe_insert($this->table, $this->set_clause);
     }
     if ($this->values_clause) {
         return safe_query('insert into ' . safe_pfx($this->table) . $this->values_clause);
     }
 }
Example #16
0
function fetch($col, $table, $key, $val, $debug = '')
{
    $key = doSlash($key);
    $val = is_int($val) ? $val : "'" . doSlash($val) . "'";
    $q = "select {$col} from " . safe_pfx($table) . " where `{$key}` = {$val} limit 1";
    if ($r = safe_query($q, $debug)) {
        $thing = mysql_num_rows($r) > 0 ? mysql_result($r, 0) : '';
        mysql_free_result($r);
        return $thing;
    }
    return false;
}
/**
 * Find an adjacent article relative to a provided threshold level.
 *
 * @param  scalar $threshold      The value to compare against
 * @param  string $s              Optional section restriction
 * @param  string $type           Lesser or greater neighbour? Either '<' (previous) or '>' (next)
 * @param  array  $atts           Attribute of article at threshold
 * @param  string $threshold_type 'cooked': Use $threshold as SQL clause; 'raw': Use $threshold as an escapable scalar
 * @return array|bool An array populated with article data, or 'false' in case of no matches
 */
function getNeighbour($threshold, $s, $type, $atts = array(), $threshold_type = 'raw')
{
    global $prefs;
    static $cache = array();
    $key = md5($threshold . $s . $type . join(n, $atts));
    if (isset($cache[$key])) {
        return $cache[$key];
    }
    extract($atts);
    $expired = $expired && $prefs['publish_expired_articles'];
    $customFields = getCustomFields();
    // Building query parts; lifted from publish.php.
    $ids = array_map('intval', do_list($id));
    $id = !$id ? '' : " AND ID IN (" . join(',', $ids) . ")";
    switch ($time) {
        case 'any':
            $time = "";
            break;
        case 'future':
            $time = " AND Posted > " . now('posted');
            break;
        default:
            $time = " AND Posted <= " . now('posted');
    }
    if (!$expired) {
        $time .= " AND (" . now('expires') . " <= Expires OR Expires = " . NULLDATETIME . ")";
    }
    $custom = '';
    if ($customFields) {
        foreach ($customFields as $cField) {
            if (isset($atts[$cField])) {
                $customPairs[$cField] = $atts[$cField];
            }
        }
        if (!empty($customPairs)) {
            $custom = buildCustomSql($customFields, $customPairs);
        }
    }
    if ($keywords) {
        $keys = doSlash(do_list($keywords));
        foreach ($keys as $key) {
            $keyparts[] = "FIND_IN_SET('" . $key . "', Keywords)";
        }
        $keywords = " AND (" . join(" OR ", $keyparts) . ")";
    }
    $sortdir = strtolower($sortdir);
    // Invert $type for ascending sortdir.
    $types = array('>' => array('desc' => '>', 'asc' => '<'), '<' => array('desc' => '<', 'asc' => '>'));
    $type = $type == '>' ? $types['>'][$sortdir] : $types['<'][$sortdir];
    // Escape threshold and treat it as a string unless explicitly told otherwise.
    if ($threshold_type != 'cooked') {
        $threshold = "'" . doSlash($threshold) . "'";
    }
    $safe_name = safe_pfx('textpattern');
    $q = array("SELECT ID AS thisid, Section AS section, Title AS title, url_title, UNIX_TIMESTAMP(Posted) AS posted\n            FROM {$safe_name} WHERE {$sortby} {$type} {$threshold}", $s != '' && $s != 'default' ? "AND Section = '" . doSlash($s) . "'" : filterFrontPage(), $id, $time, $custom, $keywords, "AND Status = 4", "ORDER BY {$sortby}", $type == '<' ? "DESC" : "ASC", "LIMIT 1");
    $cache[$key] = getRow(join(n . ' ', $q));
    return is_array($cache[$key]) ? $cache[$key] : false;
}
Example #18
0
 function drop_table()
 {
     return safe_query('DROP TABLE ' . safe_pfx($this->_table_name), $this->_debug);
 }
Example #19
0
/**
 * Processes delete actions sent using the multi-edit form.
 */
function section_delete()
{
    $selectedList = ps('selected');
    $selected = join(',', quote_list($selectedList));
    $message = '';
    $sections = safe_column("name", 'txp_section', "name != 'default' AND name IN ({$selected}) AND name NOT IN (SELECT Section FROM " . safe_pfx('textpattern') . ")");
    $sectionsNotDeleted = array_diff($selectedList, $sections);
    if ($sections && safe_delete('txp_section', "name IN (" . join(',', quote_list($sections)) . ")")) {
        callback_event('sections_deleted', '', 0, $sections);
        $message = gTxt('section_deleted', array('{name}' => join(', ', $sections)));
    }
    if ($sectionsNotDeleted) {
        $severity = $message ? E_WARNING : E_ERROR;
        $message = array(($message ? $message . n : '') . gTxt('section_delete_failure', array('{name}' => join(', ', $sectionsNotDeleted))), $severity);
    }
    sec_section_list($message);
}
Example #20
0
function recent_comments($atts, $thing = NULL)
{
    global $prefs;
    global $thisarticle, $thiscomment;
    extract(lAtts(array('break' => br, 'class' => __FUNCTION__, 'form' => '', 'label' => '', 'labeltag' => '', 'limit' => 10, 'offset' => 0, 'sort' => 'posted desc', 'wraptag' => ''), $atts));
    $sort = preg_replace('/\\bposted\\b/', 'd.posted', $sort);
    $expired = $prefs['publish_expired_articles'] ? '' : ' and (now() <= t.Expires or t.Expires = ' . NULLDATETIME . ') ';
    $rs = startRows('select d.name, d.email, d.web, d.message, d.discussid, unix_timestamp(d.Posted) as time, ' . 't.ID as thisid, unix_timestamp(t.Posted) as posted, t.Title as title, t.Section as section, t.url_title ' . 'from ' . safe_pfx('txp_discuss') . ' as d inner join ' . safe_pfx('textpattern') . ' as t on d.parentid = t.ID ' . 'where t.Status >= 4' . $expired . ' and d.visible = ' . VISIBLE . ' order by ' . doSlash($sort) . ' limit ' . intval($offset) . ',' . intval($limit));
    if ($rs) {
        $out = array();
        $old_article = $thisarticle;
        while ($c = nextRow($rs)) {
            if (empty($form) && empty($thing)) {
                $out[] = href(txpspecialchars($c['name']) . ' (' . escape_title($c['title']) . ')', permlinkurl($c) . '#c' . $c['discussid']);
            } else {
                $thiscomment['name'] = $c['name'];
                $thiscomment['email'] = $c['email'];
                $thiscomment['web'] = $c['web'];
                $thiscomment['message'] = $c['message'];
                $thiscomment['discussid'] = $c['discussid'];
                $thiscomment['time'] = $c['time'];
                // allow permlink guesstimation in permlinkurl(), elsewhere
                $thisarticle['thisid'] = $c['thisid'];
                $thisarticle['posted'] = $c['posted'];
                $thisarticle['title'] = $c['title'];
                $thisarticle['section'] = $c['section'];
                $thisarticle['url_title'] = $c['url_title'];
                $out[] = $thing ? parse($thing) : parse_form($form);
            }
        }
        if ($out) {
            unset($GLOBALS['thiscomment']);
            $thisarticle = $old_article;
            return doLabel($label, $labeltag) . doWrap($out, $wraptag, $break, $class);
        }
    }
    return '';
}
Example #21
0
function doImportWP($b2dblogin, $b2db, $b2dbpass, $b2dbhost, $wpdbprefix, $insert_into_section, $insert_with_status, $default_comment_invite, $wpdbcharset)
{
    global $txpcfg;
    $b2link = mysql_connect($b2dbhost, $b2dblogin, $b2dbpass, true);
    if (!$b2link) {
        return 'WordPress database values don&#8217;t work. Go back, replace them and try again.';
    }
    mysql_select_db($b2db, $b2link);
    if (!mysql_query('SET NAMES ' . doslash($wpdbcharset), $b2link)) {
        return 'WordPress database does not support the requested character set. Aborting.';
    }
    // Keep some response on some part
    $results = array();
    $errors = array();
    $results[] = hed('Connected to WordPress database. Importing Data&#8230;', 1);
    /*
    export users
    */
    $users = array();
    $user_query = mysql_query("\n\t\t\tselect\n\t\t\t\tID as user_id,\n\t\t\t\tuser_login as name,\n\t\t\t\tuser_email as email,\n\t\t\t\tdisplay_name as RealName\n\t\t\tfrom " . $wpdbprefix . "users\n\t\t", $b2link) or $errors[] = mysql_error();
    while ($user = mysql_fetch_array($user_query)) {
        $user_privs_query = mysql_query("\n\t\t\t\tselect\n\t\t\t\t\tmeta_value\n\t\t\t\tfrom " . $wpdbprefix . "usermeta\n\t\t\t\twhere user_id = " . $user['user_id'] . " and meta_key = '" . $wpdbprefix . "capabilities'\n\t\t\t", $b2link) or $errors[] = mysql_error();
        $privs = unserialize(mysql_result($user_privs_query, 0));
        foreach ($privs as $key => $val) {
            // convert the built-in WordPress roles
            // to their Txp equivalent
            switch ($key) {
                // publisher
                case 'administrator':
                    $user['privs'] = 1;
                    break;
                    // managing editor
                // managing editor
                case 'editor':
                    $user['privs'] = 2;
                    break;
                    // staff writer
                // staff writer
                case 'author':
                    $user['privs'] = 4;
                    break;
                    // freelancer
                // freelancer
                case 'contributor':
                    $user['privs'] = 5;
                    break;
                    // none
                // none
                case 'subscriber':
                default:
                    $user['privs'] = 0;
                    break;
            }
        }
        $users[] = $user;
    }
    /*
    export article and link categories
    */
    $categories = array();
    $category_query = mysql_query("\n\t\t\tselect\n\t\t\t\tt.slug as name,\n\t\t\t\tt.name as title,\n\t\t\t\ttt.taxonomy as type,\n\t\t\t\ttt.parent as parent\n\t\t\tfrom " . $wpdbprefix . "terms as t inner join " . $wpdbprefix . "term_taxonomy as tt\n\t\t\t\ton(t.term_id = tt.term_id)\n\t\t\torder by field(tt.taxonomy, 'category','post_tag','link_category'), tt.parent asc, t.name asc\n\t\t", $b2link) or $errors[] = mysql_error();
    while ($category = mysql_fetch_array($category_query)) {
        if ($category['parent'] != 0) {
            $category_parent_query = mysql_query("\n\t\t\t\t\tselect\n\t\t\t\t\t\tslug as name\n\t\t\t\t\tfrom " . $wpdbprefix . "terms\n\t\t\t\t\twhere term_id = '" . doSlash($category['parent']) . "'\n\t\t\t\t", $b2link) or $errors[] = mysql_error();
            while ($parent = mysql_fetch_array($category_parent_query)) {
                $category['parent'] = $parent['name'];
            }
        } else {
            $category['parent'] = 'root';
        }
        switch ($category['type']) {
            case 'post_tag':
            case 'category':
                $category['type'] = 'article';
                break;
            case 'link_category':
                $category['type'] = 'link';
                break;
        }
        $categories[] = $category;
    }
    /*
    export articles - do not export post revisions from WP 2.6+
    */
    $article_query = mysql_query("\n\t\t\tselect\n\t\t\t\tp.ID as ID,\n\t\t\t\tp.post_status as Status,\n\t\t\t\tp.post_date as Posted,\n\t\t\t\tp.post_modified as LastMod,\n\t\t\t\tp.post_title as Title,\n\t\t\t\tp.post_content as Body,\n\t\t\t\tp.comment_status as Annotate,\n\t\t\t\tp.comment_count as comments_count,\n\t\t\t\tp.post_name as url_title,\n\t\t\t\tu.user_login as AuthorID\n\t\t\tfrom " . $wpdbprefix . "posts as p left join " . $wpdbprefix . "users as u\n\t\t\t\ton u.ID = p.post_author\n\t\t\twhere p.post_type = 'post'\n\t\t\torder by p.ID asc\n\t\t", $b2link) or $errors[] = mysql_error();
    while ($article = mysql_fetch_array($article_query)) {
        // convert WP article status to Txp equivalent
        switch ($article['Status']) {
            case 'draft':
                $article['Status'] = 1;
                break;
                // hidden
            // hidden
            case 'private':
                $article['Status'] = 2;
                break;
            case 'pending':
                $article['Status'] = 3;
                break;
                // live
            // live
            case 'publish':
                $article['Status'] = 4;
                break;
            default:
                $article['Status'] = $insert_with_status;
                break;
        }
        // convert WP comment status to Txp equivalent
        switch ($article['Annotate']) {
            // on
            case 'open':
                $article['Annotate'] = 1;
                break;
                // off
            // off
            case 'closed':
            case 'registered_only':
                $article['Annotate'] = 0;
                break;
        }
        // article commments
        $comments = array();
        $comment_query = mysql_query("\n\t\t\t\tselect\n\t\t\t\t\tcomment_author_IP as ip,\n\t\t\t\t\tcomment_author as name,\n\t\t\t\t\tcomment_author_email as email,\n\t\t\t\t\tcomment_author_url as web,\n\t\t\t\t\tcomment_content as message,\n\t\t\t\t\tcomment_date as posted\n\t\t\t\tfrom " . $wpdbprefix . "comments\n\t\t\t\twhere comment_post_ID = '" . $article['ID'] . "'\n\t\t\t\torder by comment_ID asc\n\t\t\t", $b2link) or $errors[] = mysql_error();
        while ($comment = mysql_fetch_assoc($comment_query)) {
            $comments[] = $comment;
        }
        $article['comments'] = $comments;
        // article categories
        $article_categories = array();
        $article_category_query = mysql_query("\n\t\t\t\tselect\n\t\t\t\t\tt.name as title,\n\t\t\t\t\tt.slug as name\n\t\t\t\tfrom " . $wpdbprefix . "terms as t inner join " . $wpdbprefix . "term_taxonomy as tt\n\t\t\t\t\ton(t.term_id = tt.term_id)\n\t\t\t\tinner join " . $wpdbprefix . "term_relationships as tr\n\t\t\t\t\ton(tt.term_taxonomy_id = tr.term_taxonomy_id)\n\t\t\t\twhere tr.object_id = '" . $article['ID'] . "' and tt.taxonomy in('post_tag', 'category')\n\t\t\t\torder by tr.object_id asc, t.name asc\n\t\t\t\tlimit 2;\n\t\t\t", $b2link) or $errors[] = mysql_error();
        while ($category = mysql_fetch_array($article_category_query)) {
            $article_categories[] = $category;
        }
        $article['Category1'] = !empty($article_categories[0]) ? $article_categories[0]['name'] : '';
        $article['Category2'] = !empty($article_categories[1]) ? $article_categories[1]['name'] : '';
        // article images
        $article_images = array();
        $article_image_query = mysql_query("\n\t\t\tselect\n\t\t\t\tguid\n\t\t\tfrom " . $wpdbprefix . "posts\n\t\t\twhere post_type = 'attachment' and post_mime_type like 'image/%' and post_parent=" . $article['ID'], $b2link) or $errors[] = mysql_error();
        while ($image = mysql_fetch_array($article_image_query)) {
            $article_images[] = $image['guid'];
        }
        // Comma-separated image urls preserve multiple attachments.
        // Attn: If more than one image is attached, <txp:article_image /> will not work out of the box.
        $article['Image'] = join(',', $article_images);
        $articles[] = $article;
    }
    /*
    export links
    */
    $links = array();
    $link_query = mysql_query("\n\t\t\tselect\n\t\t\t\tlink_id as id,\n\t\t\t\tlink_name as linkname,\n\t\t\t\tlink_description as description,\n\t\t\t\tlink_updated as date,\n\t\t\t\tlink_url as url\n\t\t\tfrom " . $wpdbprefix . "links\n\t\t\torder by link_id asc\n\t\t", $b2link) or $errors[] = mysql_error();
    while ($link = mysql_fetch_array($link_query)) {
        // link categories
        $link_categories = array();
        $link_category_query = mysql_query("\n\t\t\t\tselect\n\t\t\t\t\tt.name as title,\n\t\t\t\t\tt.slug as name\n\t\t\t\tfrom " . $wpdbprefix . "terms as t inner join " . $wpdbprefix . "term_taxonomy as tt\n\t\t\t\t\ton(t.term_id = tt.term_id)\n\t\t\t\tinner join " . $wpdbprefix . "term_relationships as tr\n\t\t\t\t\ton(tt.term_taxonomy_id = tr.term_taxonomy_id)\n\t\t\t\twhere tr.object_id = '" . $link['id'] . "' and tt.taxonomy = 'link_category'\n\t\t\t\torder by tr.object_id asc, t.name asc\n\t\t\t", $b2link) or $errors[] = mysql_error();
        while ($category = mysql_fetch_array($link_category_query)) {
            $link['category'] = $category['name'];
        }
        $links[] = $link;
    }
    mysql_close($b2link);
    /*
    begin import
    */
    // keep a handy copy of txpdb values, and do not alter Dean code
    // for now! ;-)
    $txpdb = $txpcfg['db'];
    $txpdblogin = $txpcfg['user'];
    $txpdbpass = $txpcfg['pass'];
    $txpdbhost = $txpcfg['host'];
    // Yes, we have to make a new connection
    // otherwise doArray complains
    $DB = new DB();
    $txplink =& $DB->link;
    mysql_select_db($txpdb, $txplink);
    /*
    import users
    */
    if ($users) {
        include_once txpath . '/lib/txplib_admin.php';
        $results[] = hed('Imported Users:', 2) . n . graf('Because WordPress uses a different password mechanism than Textpattern, you will need to reset each user&#8217;s password from <a href="index.php?event=admin">the Users tab</a>.') . n . '<ul>';
        foreach ($users as $user) {
            extract($user);
            if (!safe_row('user_id', 'txp_users', "name = '" . doSlash($name) . "'")) {
                $pass = doSlash(generate_password(6));
                $nonce = doSlash(md5(uniqid(mt_rand(), TRUE)));
                $rs = mysql_query("\n\t\t\t\t\t\tinsert into " . safe_pfx('txp_users') . " set\n\t\t\t\t\t\t\tname     = '" . doSlash($name) . "',\n\t\t\t\t\t\t\tpass     = '******',\n\t\t\t\t\t\t\temail    = '" . doSlash($email) . "',\n\t\t\t\t\t\t\tRealName = '" . doSlash($RealName) . "',\n\t\t\t\t\t\t\tprivs    = " . $privs . ",\n\t\t\t\t\t\t\tnonce    = '" . doSlash($nonce) . "'\n\t\t\t\t\t", $txplink) or $errors[] = mysql_error();
                if (mysql_insert_id()) {
                    $results[] = '<li>' . $name . ' (' . $RealName . ')</li>';
                }
            }
        }
        $results[] = '</ul>';
    }
    /*
    import categories
    */
    if ($categories) {
        $results[] = hed('Imported Categories:', 2) . n . '<ul>';
        foreach ($categories as $category) {
            extract($category);
            if (!safe_row('id', 'txp_category', "name = '" . doSlash($name) . "' and type = '" . doSlash($type) . "' and parent = '" . doSlash($parent) . "'")) {
                $rs = mysql_query("\n\t\t\t\t\t\tinsert into " . safe_pfx('txp_category') . " set\n\t\t\t\t\t\t\tname   = '" . doSlash($name) . "',\n\t\t\t\t\t\t\ttitle  = '" . doSlash($title) . "',\n\t\t\t\t\t\t\ttype   = '" . doSlash($type) . "',\n\t\t\t\t\t\t\tparent = '" . doSlash($parent) . "'\n\t\t\t\t\t", $txplink) or $errors[] = mysql_error();
                if (mysql_insert_id()) {
                    $results[] = '<li>' . $title . ' (' . $type . ')</li>';
                }
            }
        }
        rebuild_tree_full('article');
        rebuild_tree_full('link');
        $results[] = '</ul>';
    }
    /*
    import articles
    */
    if ($articles) {
        $results[] = hed('Imported Articles and Comments:', 2) . n . '<ul>';
        include txpath . '/lib/classTextile.php';
        $textile = new Textile();
        foreach ($articles as $article) {
            extract($article);
            // Ugly, really ugly way to workaround the slashes WP gotcha
            $Body = str_replace('<!--more-->', '', $Body);
            $Body_html = $textile->textileThis($Body);
            // can not use array slash due to way on which comments are selected
            $rs = mysql_query("\n\t\t\t\t\tinsert into " . safe_pfx('textpattern') . " set\n\t\t\t\t\t\tPosted         = '" . doSlash($Posted) . "',\n\t\t\t\t\t\tLastMod        = '" . doSlash($LastMod) . "',\n\t\t\t\t\t\tTitle          = '" . doSlash($textile->TextileThis($Title, 1)) . "',\n\t\t\t\t\t\turl_title      = '" . doSlash($url_title) . "',\n\t\t\t\t\t\tBody           = '" . doSlash($Body) . "',\n\t\t\t\t\t\tBody_html      = '" . doSlash($Body_html) . "',\n\t\t\t\t\t\tImage          = '" . doSlash($Image) . "',\n\t\t\t\t\t\tAuthorID       = '" . doSlash($AuthorID) . "',\n\t\t\t\t\t\tCategory1      = '" . doSlash($Category1) . "',\n\t\t\t\t\t\tCategory2      = '" . doSlash($Category2) . "',\n\t\t\t\t\t\tSection        = '{$insert_into_section}',\n\t\t\t\t\t\tuid            = '" . md5(uniqid(rand(), true)) . "',\n\t\t\t\t\t\tfeed_time      = '" . substr($Posted, 0, 10) . "',\n\t\t\t\t\t\tAnnotate       = '" . doSlash($Annotate) . "',\n\t\t\t\t\t\tAnnotateInvite = '{$default_comment_invite}',\n\t\t\t\t\t\tStatus         = '" . doSlash($Status) . "'\n\t\t\t\t", $txplink) or $errors[] = mysql_error();
            if ((int) ($insert_id = mysql_insert_id($txplink))) {
                $results[] = '<li>' . $Title . '</li>';
                if (!empty($comments)) {
                    $inserted_comments = 0;
                    foreach ($comments as $comment) {
                        extract(array_slash($comment));
                        // The ugly workaroud again
                        $message = nl2br($message);
                        $rs = mysql_query("\n\t\t\t\t\t\t\t\tinsert into " . safe_pfx('txp_discuss') . " set\n\t\t\t\t\t\t\t\t\tparentid = '{$insert_id}',\n\t\t\t\t\t\t\t\t\tname     = '" . doSlash($name) . "',\n\t\t\t\t\t\t\t\t\temail    = '" . doSlash($email) . "',\n\t\t\t\t\t\t\t\t\tweb      = '" . doSlash($web) . "',\n\t\t\t\t\t\t\t\t\tip       = '" . doSlash($ip) . "',\n\t\t\t\t\t\t\t\t\tposted   = '" . doSlash($posted) . "',\n\t\t\t\t\t\t\t\t\tmessage  = '" . doSlash($message) . "',\n\t\t\t\t\t\t\t\t\tvisible  = 1\n\t\t\t\t\t\t\t", $txplink) or $results[] = mysql_error();
                        if (mysql_insert_id()) {
                            $inserted_comments++;
                        }
                    }
                    $results[] = '<li>- ' . $inserted_comments . ' of ' . $comments_count . ' comment(s)</li>';
                }
            }
        }
        $results[] = '</ul>';
    }
    /*
    import links
    */
    if ($links) {
        $results[] = hed('Imported Links:', 2) . n . '<ul>';
        foreach ($links as $link) {
            extract($link);
            $rs = mysql_query("\n\t\t\t\t\tinsert into " . safe_pfx('txp_link') . " set\n\t\t\t\t\t\tlinkname    = '" . doSlash($linkname) . "',\n\t\t\t\t\t\tlinksort    = '" . doSlash($linkname) . "',\n\t\t\t\t\t\tdescription = '" . doSlash($description) . "',\n\t\t\t\t\t\tcategory    = '" . doSlash($category) . "',\n\t\t\t\t\t\tdate        = '" . doSlash($date) . "',\n\t\t\t\t\t\turl         = '" . doSlash($url) . "'\n\t\t\t\t", $txplink) or $errors[] = mysql_error();
            if (mysql_insert_id()) {
                $results[] = '<li>' . $linkname . '</li>';
            }
        }
        $results[] = '</ul>';
    }
    /*
    show any errors we encountered
    */
    if ($errors) {
        $results[] = hed('Errors Encountered:', 2) . n . '<ul>';
        foreach ($errors as $error) {
            $results[] = '<li>' . $error . '</li>';
        }
        $results[] = '</ul>';
    }
    return join(n, $results);
}
Example #22
0
function adi_get_sections()
{
    $sql_fields = "name, title, adi_menu_parent, adi_menu_title, adi_menu_exclude, adi_menu_clone, adi_menu_sort";
    $sql_tables = safe_pfx('txp_section');
    $rs = safe_query("SELECT " . $sql_fields . " FROM " . $sql_tables . " ORDER BY name");
    while ($a = nextRow($rs)) {
        extract($a);
        // set 'name','title','parent' etc in $a
        $out[$name] = $a;
    }
    return $out;
}
Example #23
0
/**
 * The main panel listing all articles.
 *
 * @param  string|array $message The activity message
 * @param  string       $post    Not used
 */
function list_list($message = '', $post = '')
{
    global $statuses, $use_comments, $comments_disabled_after, $step, $txp_user, $article_list_pageby, $event;
    pagetop(gTxt('tab_list'), $message);
    extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method')));
    if ($sort === '') {
        $sort = get_pref('article_sort_column', 'posted');
    } else {
        if (!in_array($sort, array('id', 'title', 'expires', 'section', 'category1', 'category2', 'status', 'author', 'comments', 'lastmod'))) {
            $sort = 'posted';
        }
        set_pref('article_sort_column', $sort, 'list', 2, '', 0, PREF_PRIVATE);
    }
    if ($dir === '') {
        $dir = get_pref('article_sort_dir', 'desc');
    } else {
        $dir = $dir == 'asc' ? "asc" : "desc";
        set_pref('article_sort_dir', $dir, 'list', 2, '', 0, PREF_PRIVATE);
    }
    $sesutats = array_flip($statuses);
    switch ($sort) {
        case 'id':
            $sort_sql = "textpattern.ID {$dir}";
            break;
        case 'title':
            $sort_sql = "textpattern.Title {$dir}, textpattern.Posted DESC";
            break;
        case 'expires':
            $sort_sql = "textpattern.Expires {$dir}";
            break;
        case 'section':
            $sort_sql = "section.title {$dir}, textpattern.Posted DESC";
            break;
        case 'category1':
            $sort_sql = "category1.title {$dir}, textpattern.Posted DESC";
            break;
        case 'category2':
            $sort_sql = "category2.title {$dir}, textpattern.Posted DESC";
            break;
        case 'status':
            $sort_sql = "textpattern.Status {$dir}, textpattern.Posted DESC";
            break;
        case 'author':
            $sort_sql = "user.RealName {$dir}, textpattern.Posted DESC";
            break;
        case 'comments':
            $sort_sql = "textpattern.comments_count {$dir}, textpattern.Posted DESC";
            break;
        case 'lastmod':
            $sort_sql = "textpattern.LastMod {$dir}, textpattern.Posted DESC";
            break;
        default:
            $sort = 'posted';
            $sort_sql = "textpattern.Posted {$dir}";
            break;
    }
    $switch_dir = $dir == 'desc' ? 'asc' : 'desc';
    $search = new Filter($event, array('id' => array('column' => 'textpattern.ID', 'label' => gTxt('ID'), 'type' => 'integer'), 'title_body_excerpt' => array('column' => array('textpattern.Title', 'textpattern.Body', 'textpattern.Excerpt'), 'label' => gTxt('title_body_excerpt')), 'section' => array('column' => array('textpattern.Section', 'section.title'), 'label' => gTxt('section')), 'keywords' => array('column' => 'textpattern.Keywords', 'label' => gTxt('keywords'), 'type' => 'find_in_set'), 'categories' => array('column' => array('textpattern.Category1', 'textpattern.Category2', 'category1.title', 'category2.title'), 'label' => gTxt('categories')), 'status' => array('column' => array('textpattern.Status'), 'label' => gTxt('status'), 'type' => 'boolean'), 'author' => array('column' => array('textpattern.AuthorID', 'user.RealName'), 'label' => gTxt('author')), 'article_image' => array('column' => array('textpattern.Image'), 'label' => gTxt('article_image'), 'type' => 'integer'), 'posted' => array('column' => array('textpattern.Posted'), 'label' => gTxt('posted')), 'lastmod' => array('column' => array('textpattern.LastMod'), 'label' => gTxt('article_modified'))));
    $search->setAliases('status', $statuses);
    list($criteria, $crit, $search_method) = $search->getFilter(array('id' => array('can_list' => true), 'article_image' => array('can_list' => true), 'title_body_excerpt' => array('always_like' => true)));
    $search_render_options = array('placeholder' => 'search_articles');
    $sql_from = safe_pfx('textpattern') . " textpattern\n        LEFT JOIN " . safe_pfx('txp_category') . " category1 ON category1.name = textpattern.Category1 AND category1.type = 'article'\n        LEFT JOIN " . safe_pfx('txp_category') . " category2 ON category2.name = textpattern.Category2 AND category2.type = 'article'\n        LEFT JOIN " . safe_pfx('txp_section') . " section ON section.name = textpattern.Section\n        LEFT JOIN " . safe_pfx('txp_users') . " user ON user.name = textpattern.AuthorID";
    if ($criteria === 1) {
        $total = safe_count('textpattern', $criteria);
    } else {
        $total = getThing("SELECT COUNT(*) FROM {$sql_from} WHERE {$criteria}");
    }
    echo n . tag(hed(gTxt('tab_list'), 1, array('class' => 'txp-heading')), 'div', array('class' => 'txp-layout-2col-cell-1'));
    $searchBlock = n . tag($search->renderForm('list', $search_render_options), 'div', array('class' => 'txp-layout-2col-cell-2', 'id' => $event . '_control'));
    $createBlock = array();
    if (has_privs('article.edit')) {
        $createBlock[] = n . tag(sLink('article', '', gTxt('add_new_article'), 'txp-button'), 'div', array('class' => 'txp-control-panel'));
    }
    $contentBlockStart = n . tag_start('div', array('class' => 'txp-layout-1col', 'id' => $event . '_container'));
    $createBlock = implode(n, $createBlock);
    if ($total < 1) {
        if ($criteria != 1) {
            echo $searchBlock . $contentBlockStart . $createBlock . graf(span(null, array('class' => 'ui-icon ui-icon-info')) . ' ' . gTxt('no_results_found'), array('class' => 'alert-block information'));
        } else {
            echo $contentBlockStart . $createBlock . graf(span(null, array('class' => 'ui-icon ui-icon-info')) . ' ' . gTxt('no_articles_recorded'), array('class' => 'alert-block information'));
        }
        echo n . tag_end('div');
        return;
    }
    $limit = max($article_list_pageby, 15);
    list($page, $offset, $numPages) = pager($total, $limit, $page);
    echo $searchBlock . $contentBlockStart . $createBlock;
    $rs = safe_query("SELECT\n            textpattern.ID, textpattern.Title, textpattern.url_title, textpattern.Section,\n            textpattern.Category1, textpattern.Category2,\n            textpattern.Status, textpattern.Annotate, textpattern.AuthorID,\n            UNIX_TIMESTAMP(textpattern.Posted) AS posted,\n            UNIX_TIMESTAMP(textpattern.LastMod) AS lastmod,\n            UNIX_TIMESTAMP(textpattern.Expires) AS expires,\n            category1.title AS category1_title,\n            category2.title AS category2_title,\n            section.title AS section_title,\n            user.RealName AS RealName,\n            (SELECT COUNT(*) FROM " . safe_pfx('txp_discuss') . " WHERE parentid = textpattern.ID) AS total_comments\n        FROM {$sql_from} WHERE {$criteria} ORDER BY {$sort_sql} LIMIT {$offset}, {$limit}");
    if ($rs) {
        $show_authors = !has_single_author('textpattern', 'AuthorID');
        echo n . tag(toggle_box('articles_detail'), 'div', array('class' => 'txp-list-options')) . n . tag_start('form', array('class' => 'multi_edit_form', 'id' => 'articles_form', 'name' => 'longform', 'method' => 'post', 'action' => 'index.php')) . n . tag_start('div', array('class' => 'txp-listtables')) . n . tag_start('table', array('class' => 'txp-list')) . n . tag_start('thead') . tr(hCell(fInput('checkbox', 'select_all', 0, '', '', '', '', '', 'select_all'), '', ' class="txp-list-col-multi-edit" scope="col" title="' . gTxt('toggle_all_selected') . '"') . column_head('ID', 'id', 'list', true, $switch_dir, $crit, $search_method, ('id' == $sort ? "{$dir} " : '') . 'txp-list-col-id') . column_head('title', 'title', 'list', true, $switch_dir, $crit, $search_method, ('title' == $sort ? "{$dir} " : '') . 'txp-list-col-title') . column_head('posted', 'posted', 'list', true, $switch_dir, $crit, $search_method, ('posted' == $sort ? "{$dir} " : '') . 'txp-list-col-created date') . column_head('article_modified', 'lastmod', 'list', true, $switch_dir, $crit, $search_method, ('lastmod' == $sort ? "{$dir} " : '') . 'txp-list-col-lastmod date articles_detail') . column_head('expires', 'expires', 'list', true, $switch_dir, $crit, $search_method, ('expires' == $sort ? "{$dir} " : '') . 'txp-list-col-expires date articles_detail') . column_head('section', 'section', 'list', true, $switch_dir, $crit, $search_method, ('section' == $sort ? "{$dir} " : '') . 'txp-list-col-section') . column_head('category1', 'category1', 'list', true, $switch_dir, $crit, $search_method, ('category1' == $sort ? "{$dir} " : '') . 'txp-list-col-category1 category articles_detail') . column_head('category2', 'category2', 'list', true, $switch_dir, $crit, $search_method, ('category2' == $sort ? "{$dir} " : '') . 'txp-list-col-category2 category articles_detail') . column_head('status', 'status', 'list', true, $switch_dir, $crit, $search_method, ('status' == $sort ? "{$dir} " : '') . 'txp-list-col-status') . ($show_authors ? column_head('author', 'author', 'list', true, $switch_dir, $crit, $search_method, ('author' == $sort ? "{$dir} " : '') . 'txp-list-col-author name') : '') . ($use_comments == 1 ? column_head('comments', 'comments', 'list', true, $switch_dir, $crit, $search_method, ('comments' == $sort ? "{$dir} " : '') . 'txp-list-col-comments articles_detail') : '')) . n . tag_end('thead');
        include_once txpath . '/publish/taghandlers.php';
        echo n . tag_start('tbody');
        $validator = new Validator();
        while ($a = nextRow($rs)) {
            extract($a);
            if ($Title === '') {
                $Title = '<em>' . eLink('article', 'edit', 'ID', $ID, gTxt('untitled')) . '</em>';
            } else {
                $Title = eLink('article', 'edit', 'ID', $ID, $Title);
            }
            // Valid section and categories?
            $validator->setConstraints(array(new SectionConstraint($Section)));
            $vs = $validator->validate() ? '' : ' error';
            $validator->setConstraints(array(new CategoryConstraint($Category1, array('type' => 'article'))));
            $vc[1] = $validator->validate() ? '' : ' error';
            $validator->setConstraints(array(new CategoryConstraint($Category2, array('type' => 'article'))));
            $vc[2] = $validator->validate() ? '' : ' error';
            $Category1 = $Category1 ? span(txpspecialchars($category1_title), array('title' => $Category1)) : '';
            $Category2 = $Category2 ? span(txpspecialchars($category2_title), array('title' => $Category2)) : '';
            if ($Status != STATUS_LIVE and $Status != STATUS_STICKY) {
                $view_url = '?txpreview=' . intval($ID) . '.' . time();
            } else {
                $view_url = permlinkurl($a);
            }
            if (isset($statuses[$Status])) {
                $Status = $statuses[$Status];
            }
            $comments = '(' . $total_comments . ')';
            if ($total_comments) {
                $comments = href($comments, array('event' => 'discuss', 'step' => 'list', 'search_method' => 'parent', 'crit' => $ID), array('title' => gTxt('manage')));
            }
            $comment_status = $Annotate ? gTxt('on') : gTxt('off');
            if ($comments_disabled_after) {
                $lifespan = $comments_disabled_after * 86400;
                $time_since = time() - $posted;
                if ($time_since > $lifespan) {
                    $comment_status = gTxt('expired');
                }
            }
            $comments = tag($comment_status, 'span', array('class' => 'comments-status')) . ' ' . tag($comments, 'span', array('class' => 'comments-manage'));
            echo tr(td(($a['Status'] >= STATUS_LIVE and has_privs('article.edit.published') or $a['Status'] >= STATUS_LIVE and $AuthorID === $txp_user and has_privs('article.edit.own.published') or $a['Status'] < STATUS_LIVE and has_privs('article.edit') or $a['Status'] < STATUS_LIVE and $AuthorID === $txp_user and has_privs('article.edit.own')) ? fInput('checkbox', 'selected[]', $ID, 'checkbox') : '', '', 'txp-list-col-multi-edit') . hCell(eLink('article', 'edit', 'ID', $ID, $ID) . sp . span(span('[', array('aria-hidden' => 'true')) . href(gTxt('view'), $view_url) . span(']', array('aria-hidden' => 'true')), array('class' => 'txp-option-link articles_detail')), '', ' class="txp-list-col-id" scope="row"') . td($Title, '', 'txp-list-col-title') . td(gTime($posted), '', 'txp-list-col-created date' . ($posted < time() ? '' : ' unpublished')) . td(gTime($lastmod), '', 'txp-list-col-lastmod date articles_detail' . ($posted === $lastmod ? ' not-modified' : '')) . td($expires ? gTime($expires) : '', '', 'txp-list-col-expires date articles_detail') . td(span(txpspecialchars($section_title), array('title' => $Section)), '', 'txp-list-col-section' . $vs) . td($Category1, '', 'txp-list-col-category1 category articles_detail' . $vc[1]) . td($Category2, '', 'txp-list-col-category2 category articles_detail' . $vc[2]) . td(href($Status, $view_url, join_atts(array('title' => gTxt('view')))), '', 'txp-list-col-status') . ($show_authors ? td(span(txpspecialchars($RealName), array('title' => $AuthorID)), '', 'txp-list-col-author name') : '') . ($use_comments ? td($comments, '', 'txp-list-col-comments articles_detail') : ''));
        }
        echo n . tag_end('tbody') . n . tag_end('table') . n . tag_end('div') . list_multiedit_form($page, $sort, $dir, $crit, $search_method) . tInput() . n . tag_end('form') . n . tag_start('div', array('class' => 'txp-navigation', 'id' => $event . '_navigation')) . pageby_form('list', $article_list_pageby) . nav_form('list', $page, $numPages, $sort, $dir, $crit, $search_method, $total, $limit) . n . tag_end('div');
    }
    echo n . tag_end('div');
}
Example #24
0
/**
 * Renders a list of categories.
 *
 * @param  string $event Type of category
 * @return string HTML
 */
function cat_event_category_list($event)
{
    $rs = getTree('root', $event);
    $parent = ps('parent_cat');
    $heading = 'tab_' . ($event == 'article' ? 'list' : $event);
    $for = $rs ? ' for="' . $event . '_category_parent"' : '';
    $out = hed(gTxt($heading) . popHelp($event . '_category'), 2) . form(graf(tag(gTxt('create_new_category'), 'label', array('for' => $event . '_category_new')) . br . fInput('text', 'title', '', '', '', '', INPUT_REGULAR, '', $event . '_category_new')) . ($rs ? graf('<label' . $for . '>' . gTxt('parent') . '</label>' . br . treeSelectInput('parent_cat', $rs, $parent, $event . '_category_parent'), array('class' => 'parent')) : '') . graf(fInput('submit', '', gTxt('Create')) . eInput('category') . sInput('cat_' . $event . '_create')), '', '', 'post', $event);
    if ($rs) {
        $total_count = array();
        if ($event == 'article') {
            // Count distinct articles for both categories, avoid duplicates.
            $rs2 = getRows("SELECT category, COUNT(*) AS num FROM (\n                    SELECT ID, Category1 AS category FROM " . safe_pfx('textpattern') . "\n                        UNION\n                    SELECT ID, Category2 AS category FROM " . safe_pfx('textpattern') . "\n                ) AS t WHERE category != '' GROUP BY category");
            if ($rs2 !== false) {
                foreach ($rs2 as $a) {
                    $total_count[$a['category']] = $a['num'];
                }
            }
        } else {
            switch ($event) {
                case 'link':
                    $rs2 = safe_rows_start("category, COUNT(*) AS num", 'txp_link', "1 = 1 GROUP BY category");
                    break;
                case 'image':
                    $rs2 = safe_rows_start("category, COUNT(*) AS num", 'txp_image', "1 = 1 GROUP BY category");
                    break;
                case 'file':
                    $rs2 = safe_rows_start("category, COUNT(*) AS num", 'txp_file', "1 = 1 GROUP BY category");
                    break;
            }
            while ($a = nextRow($rs2)) {
                $name = $a['category'];
                $num = $a['num'];
                $total_count[$name] = $num;
            }
        }
        $items = array();
        foreach ($rs as $a) {
            extract($a);
            // Format count.
            switch ($event) {
                case 'article':
                    $url = 'index.php?event=list' . a . 'search_method=categories' . a . 'crit=' . $name;
                    break;
                case 'link':
                    $url = 'index.php?event=link' . a . 'search_method=category' . a . 'crit=' . $name;
                    break;
                case 'image':
                    $url = 'index.php?event=image' . a . 'search_method=category' . a . 'crit=' . $name;
                    break;
                case 'file':
                    $url = 'index.php?event=file' . a . 'search_method=category' . a . 'crit=' . $name;
                    break;
            }
            $count = isset($total_count[$name]) ? href('(' . $total_count[$name] . ')', $url) : '(0)';
            if (empty($title)) {
                $edit_link = '<em>' . eLink('category', 'cat_' . $event . '_edit', 'id', $id, gTxt('untitled')) . '</em>';
            } else {
                $edit_link = eLink('category', 'cat_' . $event . '_edit', 'id', $id, $title);
            }
            $items[] = graf(checkbox('selected[]', $id, 0) . sp . str_repeat(sp . sp, $level * 2) . $edit_link . sp . $count, ' class="level-' . $level . '"');
        }
        if ($items) {
            $out .= cat_article_multiedit_form($event, $items);
        }
    } else {
        $out .= graf(span(null, array('class' => 'ui-icon ui-icon-info')) . ' ' . gTxt('no_categories_exist'), array('class' => 'alert-block information'));
    }
    return $out;
}
Example #25
0
 public function sitemapXML()
 {
     static $mlp_installed;
     if (!isset($mlp_installed)) {
         $mlp_installed = is_callable('l10n_installed') ? call_user_func('l10n_installed', true) : false;
     }
     $out = '<?xml version="1.0" encoding="utf-8"?>';
     $out .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
     // Homepage
     $out .= $this->urlXML(hu);
     // Excluded sections
     $excluded = $GLOBALS['prefs']['jmd_sitemap_exclude'];
     $excluded = unserialize($excluded);
     foreach ($excluded as $key => $value) {
         $notIn[$key] = "'{$value}'";
     }
     $notIn = implode(',', $notIn);
     $notIn .= ",'default'";
     // List sections
     $site_langs = array();
     if ($mlp_installed) {
         $site_langs = MLPLanguageHandler::get_site_langs();
     }
     $sections = safe_column("name", "txp_section", "name not in({$notIn})");
     foreach ($sections as $section) {
         if ($mlp_installed) {
             foreach ($site_langs as $lang) {
                 $lang = substr($lang, 0, 2) . '/';
                 $loc = hu . $lang . urlencode($section) . '/';
                 $out .= $this->urlXML($loc);
             }
         } else {
             $loc = pagelinkurl(array('s' => $section));
             $out .= $this->urlXML($loc);
         }
     }
     // Articles
     $fields = 'ID as thisid, Section as section, Title as title,
         url_title, unix_timestamp(Posted) as posted,
         unix_timestamp(LastMod) as lastmod';
     if ($mlp_installed) {
         $fields .= ', l10n_lang';
     }
     $articles = getRows("select {$fields} from " . safe_pfx('textpattern') . " where Status = 4 and Posted<= now() and section not in({$notIn})");
     if ($articles) {
         include_once txpath . '/publish/taghandlers.php';
         foreach ($articles as $article) {
             $loc = permlinkurl($article);
             if ($mlp_installed) {
                 $loc = str_replace(hu, hu . substr($article['l10n_lang'], 0, 2) . '/', $loc);
             }
             $lastmod = date('c', $article['lastmod']);
             $out .= $this->urlXML($loc, $lastmod);
         }
     }
     $out .= '</urlset>';
     return $out;
 }
Example #26
0
function getNeighbour($Posted, $s, $type)
{
    $type = $type == '>' ? '>' : '<';
    $safe_name = safe_pfx('textpattern');
    $q = array("select ID, Title, url_title, unix_timestamp(Posted) as uposted\n\t\t\tfrom " . $safe_name . " where Posted {$type} '" . doSlash($Posted) . "'", $s != '' && $s != 'default' ? "and Section = '" . doSlash($s) . "'" : filterFrontPage(), 'and Status=4 and Posted < now() order by Posted', $type == '<' ? 'desc' : 'asc', 'limit 1');
    $out = getRow(join(' ', $q));
    return is_array($out) ? $out : '';
}
Example #27
0
/**
 * Find an adjacent article relative to a provided threshold level
 *
 * @param scalar $threshold The value to compare against
 * @param string $s string Optional section restriction
 * @param string $type string Find lesser or greater neighbour? Possible values: '<' (previous, default) or '>' (next)
 * @param array $atts Attribute of article at threshold
 * @param string $threshold_type 'cooked': Use $threshold as SQL clause; 'raw': Use $threshold as an escapable scalar
 * @return array|string An array populated with article data, or the empty string in case of no matches
 */
function getNeighbour($threshold, $s, $type, $atts = array(), $threshold_type = 'raw')
{
    global $prefs;
    static $cache = array();
    $key = md5($threshold . $s . $type . join(n, $atts));
    if (isset($cache[$key])) {
        return $cache[$key];
    }
    extract($atts);
    $expired = $expired && $prefs['publish_expired_articles'];
    $customFields = getCustomFields();
    //Building query parts
    // lifted from publish.php. This is somewhat embarrassing, isn't it?
    $ids = array_map('intval', do_list($id));
    $id = !$id ? '' : " and ID IN (" . join(',', $ids) . ")";
    switch ($time) {
        case 'any':
            $time = "";
            break;
        case 'future':
            $time = " and Posted > now()";
            break;
        default:
            $time = " and Posted <= now()";
    }
    if (!$expired) {
        $time .= " and (now() <= Expires or Expires = " . NULLDATETIME . ")";
    }
    $custom = '';
    if ($customFields) {
        foreach ($customFields as $cField) {
            if (isset($atts[$cField])) {
                $customPairs[$cField] = $atts[$cField];
            }
        }
        if (!empty($customPairs)) {
            $custom = buildCustomSql($customFields, $customPairs);
        }
    }
    if ($keywords) {
        $keys = doSlash(do_list($keywords));
        foreach ($keys as $key) {
            $keyparts[] = "FIND_IN_SET('" . $key . "',Keywords)";
        }
        $keywords = " and (" . join(' or ', $keyparts) . ")";
    }
    // invert $type for ascending sortdir
    $types = array('>' => array('desc' => '>', 'asc' => '<'), '<' => array('desc' => '<', 'asc' => '>'));
    $type = $type == '>' ? $types['>'][$sortdir] : $types['<'][$sortdir];
    // escape threshold and treat it as a string unless explicitly told otherwise
    if ($threshold_type != 'cooked') {
        $threshold = "'" . doSlash($threshold) . "'";
    }
    $safe_name = safe_pfx('textpattern');
    $q = array("select ID, Title, url_title, unix_timestamp(Posted) as uposted\n\t\t\tfrom " . $safe_name . " where {$sortby} {$type} " . $threshold, $s != '' && $s != 'default' ? "and Section = '" . doSlash($s) . "'" : filterFrontPage(), $id, $time, $custom, $keywords, 'and Status=4', 'order by ' . $sortby, $type == '<' ? 'desc' : 'asc', 'limit 1');
    $cache[$key] = getRow(join(n . ' ', $q));
    return is_array($cache[$key]) ? $cache[$key] : '';
}
Example #28
0
 /**
  * Pushes content to $this->categories and $this->images
  */
 private function getImages()
 {
     $this->images = getRows("select id, name, category, ext, w, h, thumbnail\n            from " . safe_pfx('txp_image'));
     if ($this->images) {
         foreach ($this->images as $img) {
             if (!in_array($img['category'], $this->categories) && $img['category'] !== '') {
                 array_push($this->categories, $img['category']);
             }
         }
     }
 }
Example #29
0
// <txp:message /> is dropped
safe_update('txp_form', "Form = REPLACE(Form, '<txp:message', '<txp:comment_message')", "1 = 1");
// Expiry datetime for articles
safe_upgrade_table('textpattern', array('Expires' => "datetime NOT NULL default '0000-00-00 00:00:00' after `Posted`"));
if (!safe_field('name', 'txp_prefs', "name = 'publish_expired_articles'")) {
    safe_insert('txp_prefs', "prefs_id = 1, name = 'publish_expired_articles', val = '0', type = '1', event='publish', html='yesnoradio', position='130'");
}
/*
 * @todo determine section:article relation key
 */
// populate section_id values
// foreach (safe_rows('id, name', 'txp_section', '1=1') as $row) {
//	safe_update('textpattern', "section_id='".doSlash($row['id'])."'", "Section='".doSlash($row['name'])."'");
//}
// fix up the parent field in txp_category
safe_query("alter ignore table " . safe_pfx('txp_category') . " modify parent INT not null");
$types = safe_column('distinct type', 'txp_category', '1=1');
foreach ($types as $type) {
    $root = safe_field('id', 'txp_category', "type='" . doSlash($type) . "' and name='root' and parent=0");
    if (!$root) {
        $root = safe_insert('txp_category', "name='root', type='" . doSlash($type) . "', parent=0");
    }
    safe_update('txp_category', "parent='" . $root . "'", "type='" . doSlash($type) . "' and parent=0 and id != '" . $root . "'");
    tree_rebuild_full('txp_category', "type='" . doSlash($type) . "'");
}
// index on form type
safe_upgrade_index('txp_form', 'type_idx', '', 'type');
// dropdown ui for certain prefs
safe_upgrade_table('txp_prefs', array('choices' => 'varchar(64)'));
safe_update('txp_prefs', "html='checkbox'", "html='yesnoradio'");
safe_update('txp_prefs', "html='text'", "html='text_input'");
Example #30
0
/**
 * Update the plugin and return a message
 *
 * @return string Message
 */
function yab_shop_update()
{
    global $yab_shop_prefs, $plugins_ver;
    $old = $yab_shop_prefs['yab_shop_version'];
    $new = $plugins_ver['yab_shop_admin'];
    // update from 0.8.0
    if ($old == '' or $old == '0.8.0') {
        $rs[] = "update " . safe_pfx('yab_shop_lang') . " set val='Yab Shop Preferences' where name='shop_prefs' AND lang='en-gb'";
        $rs[] = "update " . safe_pfx('yab_shop_lang') . " set val='Yab Shop language saved.' where name='lang_updated' AND lang='en-gb'";
        $rs[] = "update " . safe_pfx('yab_shop_lang') . " set val='Hit the button to update Yab Shop.' where name='klick_to_update' AND lang='en-gb'";
        $rs[] = "update " . safe_pfx('yab_shop_lang') . " set val='Yab Shop database tables deleted.' where name='tables_delete_success' AND lang='en-gb'";
        $rs[] = "update " . safe_pfx('yab_shop_lang') . " set val='Yab Shop preferences saved.' where name='prefs_updated' AND lang='en-gb'";
        $rs[] = "update " . safe_pfx('yab_shop_lang') . " set val='Yab Shop public language and localisation' where name='lang_public' AND lang='en-gb'";
        $rs[] = "update " . safe_pfx('yab_shop_lang') . " set val='Yab Shop L10n' where name='shop_lang' AND lang='en-gb'";
        $rs[] = "update " . safe_pfx('yab_shop_lang') . " set val='Yab Shop common preferences' where name='shop_common_prefs' AND lang='en-gb'";
        $rs[] = "update " . safe_pfx('yab_shop_prefs') . " set val='0.8.1' where name='yab_shop_version'";
    }
    foreach ($rs as $query) {
        $result = safe_query($query);
        if (!$result) {
            return 'Could not update plugin from version ' . $old . ' to version ' . $new;
        }
    }
    return 'Plugin successfully updated to version ' . $new;
}