Ejemplo n.º 1
0
function article_edit($message = '', $concurrent = FALSE)
{
    global $vars, $txp_user, $comments_disabled_after, $txpcfg, $prefs;
    extract($prefs);
    extract(gpsa(array('view', 'from_view', 'step')));
    if (!empty($GLOBALS['ID'])) {
        // newly-saved article
        $ID = $GLOBALS['ID'];
        $step = 'edit';
    } else {
        $ID = gps('ID');
    }
    include_once txpath . '/lib/classTextile.php';
    $textile = new Textile();
    // switch to 'text' view upon page load and after article post
    if (!$view || gps('save') || gps('publish')) {
        $view = 'text';
    }
    if (!$step) {
        $step = "create";
    }
    if ($step == "edit" && $view == "text" && !empty($ID) && $from_view != 'preview' && $from_view != 'html' && !$concurrent) {
        $pull = true;
        //-- it's an existing article - off we go to the db
        $ID = assert_int($ID);
        $rs = safe_row("*, unix_timestamp(Posted) as sPosted,\n\t\t\t\tunix_timestamp(Expires) as sExpires,\n\t\t\t\tunix_timestamp(LastMod) as sLastMod", "textpattern", "ID={$ID}");
        extract($rs);
        $reset_time = $publish_now = $Status < 4;
    } else {
        $pull = false;
        //-- assume they came from post
        if ($from_view == 'preview' or $from_view == 'html') {
            $store_out = array();
            $store = unserialize(base64_decode(ps('store')));
            foreach ($vars as $var) {
                if (isset($store[$var])) {
                    $store_out[$var] = $store[$var];
                }
            }
        } else {
            $store_out = gpsa($vars);
            if ($concurrent) {
                $store_out['sLastMod'] = safe_field('unix_timestamp(LastMod) as sLastMod', 'textpattern', 'ID=' . $ID);
            }
        }
        extract($store_out);
    }
    $GLOBALS['step'] = $step;
    if ($step == 'create') {
        $textile_body = $use_textile;
        $textile_excerpt = $use_textile;
    }
    if ($step != 'create') {
        // Previous record?
        $prev_id = checkIfNeighbour('prev', $sPosted);
        // Next record?
        $next_id = checkIfNeighbour('next', $sPosted);
    }
    $page_title = $Title ? $Title : gTxt('write');
    pagetop($page_title, $message);
    echo n . n . '<form name="article" method="post" action="index.php">';
    if (!empty($store_out)) {
        echo hInput('store', base64_encode(serialize($store_out)));
    }
    echo hInput('ID', $ID) . eInput('article') . sInput($step) . '<input type="hidden" name="view" />' . startTable('edit') . '<tr>' . n . '<td id="article-col-1">';
    if ($view == 'text') {
        //-- markup help --------------
        echo side_help($textile_body, $textile_excerpt) . '<h3 class="plain"><a href="#advanced" onclick="toggleDisplay(\'advanced\'); return false;">' . gTxt('advanced_options') . '</a></h3>', '<div id="advanced" class="toggle" style="display:none">', n . graf('<label for="markup-body">' . gTxt('article_markup') . '</label>' . br . pref_text('textile_body', $textile_body, 'markup-body')), n . graf('<label for="markup-excerpt">' . gTxt('excerpt_markup') . '</label>' . br . pref_text('textile_excerpt', $textile_excerpt, 'markup-excerpt')), $allow_form_override ? graf('<label for="override-form">' . gTxt('override_default_form') . '</label>' . sp . popHelp('override_form') . br . form_pop($override_form, 'override-form')) : '', $custom_1_set ? custField(1, $custom_1_set, $custom_1) : '', $custom_2_set ? custField(2, $custom_2_set, $custom_2) : '', $custom_3_set ? custField(3, $custom_3_set, $custom_3) : '', $custom_4_set ? custField(4, $custom_4_set, $custom_4) : '', $custom_5_set ? custField(5, $custom_5_set, $custom_5) : '', $custom_6_set ? custField(6, $custom_6_set, $custom_6) : '', $custom_7_set ? custField(7, $custom_7_set, $custom_7) : '', $custom_8_set ? custField(8, $custom_8_set, $custom_8) : '', $custom_9_set ? custField(9, $custom_9_set, $custom_9) : '', $custom_10_set ? custField(10, $custom_10_set, $custom_10) : '', n . graf('<label for="keywords">' . gTxt('keywords') . '</label>' . sp . popHelp('keywords') . br . n . '<textarea id="keywords" name="Keywords" cols="18" rows="5">' . htmlspecialchars(str_replace(',', ', ', $Keywords)) . '</textarea>'), n . graf('<label for="article-image">' . gTxt('article_image') . '</label>' . sp . popHelp('article_image') . br . fInput('text', 'Image', $Image, 'edit', '', '', 22, '', 'article-image')), n . graf('<label for="url-title">' . gTxt('url_title') . '</label>' . sp . popHelp('url_title') . br . fInput('text', 'url_title', $url_title, 'edit', '', '', 22, '', 'url-title')), '</div>

			<h3 class="plain"><a href="#recent" onclick="toggleDisplay(\'recent\'); return false;">' . gTxt('recent_articles') . '</a>' . '</h3>' . '<div id="recent" class="toggle" style="display:none">';
        $recents = safe_rows_start("Title, ID", 'textpattern', "1=1 order by LastMod desc limit 10");
        if ($recents) {
            echo '<ul class="plain-list">';
            while ($recent = nextRow($recents)) {
                if (!$recent['Title']) {
                    $recent['Title'] = gTxt('untitled') . sp . $recent['ID'];
                }
                echo n . t . '<li><a href="?event=article' . a . 'step=edit' . a . 'ID=' . $recent['ID'] . '">' . escape_title($recent['Title']) . '</a></li>';
            }
            echo '</ul>';
        }
        echo '</div>';
    } else {
        echo sp;
    }
    echo '</td>' . n . '<td id="article-main">';
    //-- title input --------------
    if ($view == 'preview') {
        echo hed(gTxt('preview'), 2) . hed($Title, 1);
    } elseif ($view == 'html') {
        echo hed('XHTML', 2) . hed($Title, 1);
    } elseif ($view == 'text') {
        echo n . '<p><label for="title">' . gTxt('title') . '</label>' . sp . popHelp('title') . br . '<input type="text" id="title" name="Title" value="' . escape_title($Title) . '" class="edit" size="40" tabindex="1" />';
        if ($step != 'create') {
            include_once txpath . '/publish/taghandlers.php';
            $url = permlinkurl_id($ID);
            if ($Status != 4 and $Status != 5) {
                $url .= (strpos($url, '?') === FALSE ? '?' : '&amp;') . 'txpreview=' . intval($ID) . '.' . time();
            }
            echo sp . sp . '<a href="' . $url . '" class="article-view">' . gTxt('view') . '</a>';
        }
        echo '</p>';
    }
    //-- body --------------------
    if ($view == 'preview') {
        if ($textile_body == USE_TEXTILE) {
            echo $textile->TextileThis($Body);
        } else {
            if ($textile_body == CONVERT_LINEBREAKS) {
                echo nl2br($Body);
            } else {
                if ($textile_body == LEAVE_TEXT_UNTOUCHED) {
                    echo $Body;
                }
            }
        }
    } elseif ($view == 'html') {
        if ($textile_body == USE_TEXTILE) {
            $bod = $textile->TextileThis($Body);
        } else {
            if ($textile_body == CONVERT_LINEBREAKS) {
                $bod = nl2br($Body);
            } else {
                if ($textile_body == LEAVE_TEXT_UNTOUCHED) {
                    $bod = $Body;
                }
            }
        }
        echo tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), htmlspecialchars($bod)), 'code');
    } else {
        echo n . graf('<label for="body">' . gTxt('body') . '</label>' . sp . popHelp('body') . br . '<textarea id="body" name="Body" cols="55" rows="31" tabindex="2">' . htmlspecialchars($Body) . '</textarea>');
    }
    //-- excerpt --------------------
    if ($articles_use_excerpts) {
        if ($view == 'text') {
            echo n . graf('<label for="excerpt">' . gTxt('excerpt') . '</label>' . sp . popHelp('excerpt') . br . '<textarea id="excerpt" name="Excerpt" cols="55" rows="5" tabindex="3">' . htmlspecialchars($Excerpt) . '</textarea>');
        } else {
            echo n . '<hr width="50%" />';
            echo $textile_excerpt == USE_TEXTILE ? $view == 'preview' ? graf($textile->textileThis($Excerpt)) : tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), htmlspecialchars($textile->TextileThis($Excerpt))), 'code') : graf($Excerpt);
        }
    }
    //-- author --------------
    if ($view == "text" && $step != "create") {
        echo '<p class="small">' . gTxt('posted_by') . ': ' . htmlspecialchars($AuthorID) . ' &#183; ' . safe_strftime('%d %b %Y &#183; %X', $sPosted);
        if ($sPosted != $sLastMod) {
            echo br . gTxt('modified_by') . ': ' . htmlspecialchars($LastModID) . ' &#183; ' . safe_strftime('%d %b %Y &#183; %X', $sLastMod);
        }
        echo '</p>';
    }
    echo hInput('from_view', $view), '</td>';
    echo '<td id="article-tabs">';
    //-- layer tabs -------------------
    echo $use_textile == USE_TEXTILE || $textile_body == USE_TEXTILE ? '<ul>' . (tab('text', $view) . tab('html', $view) . tab('preview', $view)) . '</ul>' : '&#160;';
    echo '</td>';
    echo '<td id="article-col-2">';
    if ($view == 'text') {
        if ($step != 'create') {
            echo n . graf(href(gtxt('create_new'), 'index.php?event=article'));
        }
        //-- prev/next article links --
        if ($step != 'create' and ($prev_id or $next_id)) {
            echo '<p>', $prev_id ? prevnext_link('&#8249;' . gTxt('prev'), 'article', 'edit', $prev_id, gTxt('prev')) : '', $next_id ? prevnext_link(gTxt('next') . '&#8250;', 'article', 'edit', $next_id, gTxt('next')) : '', '</p>';
        }
        //-- status radios --------------
        echo n . n . '<fieldset id="write-status">' . n . '<legend>' . gTxt('status') . '</legend>' . n . status_radio($Status) . n . '</fieldset>';
        //-- category selects -----------
        echo n . n . '<fieldset id="write-sort">' . n . '<legend>' . gTxt('sort_display') . '</legend>' . n . graf('<label for="category-1">' . gTxt('category1') . '</label> ' . '<span class="small">[' . eLink('category', '', '', '', gTxt('edit')) . ']</span>' . br . n . category_popup('Category1', $Category1, 'category-1')) . n . graf('<label for="category-2">' . gTxt('category2') . '</label>' . br . n . category_popup('Category2', $Category2, 'category-2'));
        //-- section select --------------
        if (!$from_view && !$pull) {
            $Section = getDefaultSection();
        }
        echo n . graf('<label for="section">' . gTxt('section') . '</label> ' . '<span class="small">[' . eLink('section', '', '', '', gTxt('edit')) . ']</span>' . br . section_popup($Section, 'section')) . n . '</fieldset>' . n . n . '<h3 class="plain"><a href="#more" onclick="toggleDisplay(\'more\'); return false;">' . gTxt('more') . '</a></h3>', '<div id="more" class="toggle" style="display:none">';
        //-- comments stuff --------------
        if ($step == "create") {
            //Avoiding invite disappear when previewing
            $AnnotateInvite = !empty($store_out['AnnotateInvite']) ? $store_out['AnnotateInvite'] : $comments_default_invite;
            if ($comments_on_default == 1) {
                $Annotate = 1;
            }
        }
        if ($use_comments == 1) {
            echo n . n . '<fieldset id="write-comments">' . n . '<legend>' . gTxt('comments') . '</legend>';
            $comments_expired = false;
            if ($step != 'create' && $comments_disabled_after) {
                $lifespan = $comments_disabled_after * 86400;
                $time_since = time() - $sPosted;
                if ($time_since > $lifespan) {
                    $comments_expired = true;
                }
            }
            if ($comments_expired) {
                echo n . n . graf(gTxt('expired'));
            } else {
                echo n . n . graf(onoffRadio('Annotate', $Annotate)) . n . n . graf('<label for="comment-invite">' . gTxt('comment_invitation') . '</label>' . br . fInput('text', 'AnnotateInvite', $AnnotateInvite, 'edit', '', '', '', '', 'comment-invite'));
            }
            echo n . n . '</fieldset>';
        }
        if ($step == "create" and empty($GLOBALS['ID'])) {
            //-- timestamp -------------------
            //Avoiding modified date to disappear
            $persist_timestamp = !empty($store_out['year']) ? safe_strtotime($store_out['year'] . '-' . $store_out['month'] . '-' . $store_out['day'] . ' ' . $store_out['hour'] . ':' . $store_out['minute'] . ':' . $store_out['second']) : time();
            echo n . n . '<fieldset id="write-timestamp">' . n . '<legend>' . gTxt('timestamp') . '</legend>' . n . graf(checkbox('publish_now', '1', $publish_now, '', 'publish_now') . '<label for="publish_now">' . gTxt('set_to_now') . '</label>') . n . graf(gTxt('or_publish_at') . sp . popHelp('timestamp')) . n . graf(gtxt('date') . sp . tsi('year', '%Y', $persist_timestamp) . ' / ' . tsi('month', '%m', $persist_timestamp) . ' / ' . tsi('day', '%d', $persist_timestamp)) . n . graf(gTxt('time') . sp . tsi('hour', '%H', $persist_timestamp) . ' : ' . tsi('minute', '%M', $persist_timestamp) . ' : ' . tsi('second', '%S', $persist_timestamp)) . n . '</fieldset>';
            //-- expires -------------------
            $persist_timestamp = !empty($store_out['exp_year']) ? safe_strtotime($store_out['exp_year'] . '-' . $store_out['exp_month'] . '-' . $store_out['exp_day'] . ' ' . $store_out['exp_hour'] . ':' . $store_out['exp_minute'] . ':' . $store_out['second']) : NULLDATETIME;
            echo n . n . '<fieldset id="write-expires">' . n . '<legend>' . gTxt('expires') . '</legend>' . n . graf(gtxt('date') . sp . tsi('exp_year', '%Y', $persist_timestamp) . ' / ' . tsi('exp_month', '%m', $persist_timestamp) . ' / ' . tsi('exp_day', '%d', $persist_timestamp)) . n . graf(gTxt('time') . sp . tsi('exp_hour', '%H', $persist_timestamp) . ' : ' . tsi('exp_minute', '%M', $persist_timestamp) . ' : ' . tsi('exp_second', '%S', $persist_timestamp)) . n . '</fieldset>' . n . n . '</div>';
            //-- publish button --------------
            echo has_privs('article.publish') ? fInput('submit', 'publish', gTxt('publish'), "publish", '', '', '', 4) : fInput('submit', 'publish', gTxt('save'), "publish", '', '', '', 4);
        } else {
            //-- timestamp -------------------
            if (!empty($year)) {
                $sPosted = safe_strtotime($year . '-' . $month . '-' . $day . ' ' . $hour . ':' . $minute . ':' . $second);
            }
            echo n . n . '<fieldset id="write-timestamp">' . n . '<legend>' . gTxt('timestamp') . '</legend>' . n . graf(checkbox('reset_time', '1', $reset_time, '', 'reset_time') . '<label for="reset_time">' . gTxt('reset_time') . '</label>') . n . graf(gTxt('published_at') . sp . popHelp('timestamp')) . n . graf(gtxt('date') . sp . tsi('year', '%Y', $sPosted) . ' / ' . tsi('month', '%m', $sPosted) . ' / ' . tsi('day', '%d', $sPosted)) . n . graf(gTxt('time') . sp . tsi('hour', '%H', $sPosted) . ' : ' . tsi('minute', '%M', $sPosted) . ' : ' . tsi('second', '%S', $sPosted)) . n . hInput('sPosted', $sPosted), n . hInput('sLastMod', $sLastMod), n . hInput('AuthorID', $AuthorID), n . hInput('LastModID', $LastModID), n . '</fieldset>';
            //-- expires -------------------
            if (!empty($exp_year)) {
                if (empty($exp_month)) {
                    $exp_month = 1;
                }
                if (empty($exp_day)) {
                    $exp_day = 1;
                }
                if (empty($exp_hour)) {
                    $exp_hour = 0;
                }
                if (empty($exp_minute)) {
                    $exp_minute = 0;
                }
                if (empty($exp_second)) {
                    $exp_second = 0;
                }
                $sExpires = safe_strtotime($exp_year . '-' . $exp_month . '-' . $exp_day . ' ' . $exp_hour . ':' . $exp_minute . ':' . $exp_second);
            }
            echo n . n . '<fieldset id="write-expires">' . n . '<legend>' . gTxt('expires') . '</legend>' . n . graf(gtxt('date') . sp . tsi('exp_year', '%Y', $sExpires) . ' / ' . tsi('exp_month', '%m', $sExpires) . ' / ' . tsi('exp_day', '%d', $sExpires)) . n . graf(gTxt('time') . sp . tsi('exp_hour', '%H', $sExpires) . ' : ' . tsi('exp_minute', '%M', $sExpires) . ' : ' . tsi('exp_second', '%S', $sExpires)) . n . hInput('sExpires', $sExpires) . n . '</fieldset>' . n . n . '</div>';
            //-- save button --------------
            if ($Status >= 4 and has_privs('article.edit.published') or $Status >= 4 and $AuthorID == $txp_user and has_privs('article.edit.own.published') or $Status < 4 and has_privs('article.edit') or $Status < 4 and $AuthorID == $txp_user and has_privs('article.edit.own')) {
                echo fInput('submit', 'save', gTxt('save'), "publish", '', '', '', 4);
            }
        }
    }
    echo '</td></tr></table></form>';
}
Ejemplo n.º 2
0
function article_edit($message = "")
{
    global $txpcfg, $txp_user, $vars;
    extract(get_prefs());
    extract(gpsa(array('view', 'from_view', 'step')));
    if (!empty($GLOBALS['ID'])) {
        // newly-saved article
        $ID = intval($GLOBALS['ID']);
        $step = 'edit';
    } else {
        $ID = gps('ID');
    }
    include_once $txpcfg['txpath'] . '/lib/classTextile.php';
    $textile = new Textile();
    if (!$view) {
        $view = "text";
    }
    if (!$step) {
        $step = "create";
    }
    if ($step == "edit" && $view == "text" && !empty($ID) && $from_view != "preview" && $from_view != 'html') {
        $pull = true;
        //-- it's an existing article - off we go to the db
        $rs = safe_row("*, unix_timestamp(Posted) as sPosted,\n\t\t\t\tunix_timestamp(LastMod) as sLastMod", "textpattern", "ID={$ID}");
        extract($rs);
        if ($AnnotateInvite != $comments_default_invite) {
            $AnnotateInvite = $AnnotateInvite;
        } else {
            $AnnotateInvite = $comments_default_invite;
        }
    } else {
        $pull = false;
        //-- assume they came from post
        if (!$from_view or $from_view == 'text') {
            extract(gpsa($vars));
        } elseif ($from_view == 'preview' or $from_view == 'html') {
            // coming from either html or preview
            if (isset($_POST['store'])) {
                $store = unserialize(base64_decode($_POST['store']));
                extract($store);
            }
        }
        foreach ($vars as $var) {
            if (isset(${$var})) {
                $store_out[$var] = ${$var};
            }
        }
    }
    $GLOBALS['step'] = $step;
    if ($step == 'create') {
        $textile_body = 1;
        $textile_excerpt = 1;
    }
    if ($step != 'create') {
        // Previous record?
        $prev_id = checkIfNeighbour('prev', $sPosted);
        // Next record?
        $next_id = checkIfNeighbour('next', $sPosted);
    }
    pagetop($Title, $message);
    echo '<form action="index.php" method="post" name="article">';
    if (!empty($store_out)) {
        echo hInput('store', base64_encode(serialize($store_out)));
    }
    echo hInput('ID', $ID), eInput('article'), sInput($step);
    echo '<input type="hidden" name="view" />', startTable('edit');
    echo '<tr><td>&nbsp;</td><td colspan="3">', $view == 'preview' ? hed(ucfirst(gTxt('preview')), 2) . graf($Title) : '', $view == 'html' ? hed('XHTML', 2) . graf($Title) : '', $view == 'text' ? br . '<input type="text" name="Title" value="' . cleanfInput($Title) . '" class="edit" size="40" tabindex="1" />' : '', '</td></tr>';
    //-- article input --------------
    echo '<tr>
  		<td valign="top">', $view == 'text' && $use_textile == 2 ? '<p><a href="#" onclick="toggleDisplay(\'textile_help\');">' . gTxt('textile_help') . '</a></p>
		<div id="textile_help" style="display:none;">' . sidehelp() . '</div>' : sp;
    if ($view == 'text') {
        echo '<p><a href="#" onclick="toggleDisplay(\'advanced\');">' . gTxt('advanced_options') . '</a></p>', '<div id="advanced" style="display:none;">', graf(gTxt('use_textile') . br . tag(checkbox2('textile_body', $textile_body) . gTxt('article'), 'label') . br . tag(checkbox2('textile_excerpt', $textile_excerpt) . gTxt('excerpt'), 'label')), $allow_form_override ? graf(gTxt('override_default_form') . br . form_pop($override_form) . popHelp('override_form')) : '', $custom_1_set ? custField(1, $custom_1_set, $custom_1) : '', $custom_2_set ? custField(2, $custom_2_set, $custom_2) : '', $custom_3_set ? custField(3, $custom_3_set, $custom_3) : '', $custom_4_set ? custField(4, $custom_4_set, $custom_4) : '', $custom_5_set ? custField(5, $custom_5_set, $custom_5) : '', $custom_6_set ? custField(6, $custom_6_set, $custom_6) : '', $custom_7_set ? custField(7, $custom_7_set, $custom_7) : '', $custom_8_set ? custField(8, $custom_8_set, $custom_8) : '', $custom_9_set ? custField(9, $custom_9_set, $custom_9) : '', $custom_10_set ? custField(10, $custom_10_set, $custom_10) : '', graf(gTxt('keywords') . popHelp('keywords') . br . '<textarea name="Keywords" style="width:100px;height:80px" rows="1" cols="1">' . $Keywords . '</textarea>'), graf(gTxt('article_image') . popHelp('article_image') . br . fInput('text', 'Image', $Image, 'edit')), graf(gTxt('url_title') . popHelp('url_title') . br . fInput('text', 'url_title', $url_title, 'edit')) . '</div>
			
			<p><a href="#" onclick="toggleDisplay(\'recent\');">' . gTxt('recent_articles') . '</a>' . '</p>' . '<div id="recent" style="display:none;">';
        $recents = safe_rows_start("Title, ID", 'textpattern', "1 order by LastMod desc limit 10");
        if ($recents) {
            echo '<p>';
            while ($recent = nextRow($recents)) {
                extract($recent);
                if (!$Title) {
                    $Title = gTxt('untitled') . sp . $ID;
                }
                echo '<a href="?event=article' . a . 'step=edit' . a . 'ID=' . $ID . '">' . $Title . '</a>' . br . n;
            }
            echo '</p>';
        }
        echo '</div>';
    } else {
        echo sp;
    }
    echo '</td>
    	<td valign="top" style="width:400px">';
    if ($view == "preview") {
        if ($use_textile == 2) {
            echo $textile->TextileThis($Body);
        } else {
            if ($use_textile == 1) {
                echo nl2br($Body);
            } else {
                if ($use_textile == 0) {
                    echo $Body;
                }
            }
        }
    } elseif ($view == "html") {
        if ($use_textile == 2) {
            $bod = $textile->TextileThis($Body);
        } else {
            if ($use_textile == 1) {
                $bod = nl2br($Body);
            } else {
                if ($use_textile == 0) {
                    $bod = $Body;
                }
            }
        }
        echo tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), htmlspecialchars($bod)), 'code');
    } else {
        echo '<textarea style="width:400px;height:420px" rows="1" cols="1" name="Body" tabindex="2">', htmlspecialchars($Body), '</textarea>';
    }
    //-- excerpt --------------------
    if ($articles_use_excerpts) {
        if ($view == 'text') {
            $Excerpt = str_replace("&amp;", "&", htmlspecialchars($Excerpt));
            echo graf(gTxt('excerpt') . popHelp('excerpt') . br . '<textarea style="width:400px;height:50px" rows="1" cols="1" name="Excerpt" tabindex="3">' . $Excerpt . '</textarea>');
        } else {
            echo '<hr width="50%" />';
            echo $textile_excerpt ? $view == 'preview' ? graf($textile->textileThis($Excerpt), 1) : tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), htmlspecialchars($textile->TextileThis($Excerpt), 1)), 'code') : graf($Excerpt);
        }
    }
    //-- author --------------
    if ($view == "text" && $step != "create") {
        echo "<p><small>" . gTxt('posted_by') . " {$AuthorID}: ", date("H:i, d M y", $sPosted + tz_offset());
        if ($sPosted != $sLastMod) {
            echo br . gTxt('modified_by') . " {$LastModID}: ", date("H:i, d M y", $sLastMod + tz_offset());
        }
        echo '</small></p>';
    }
    echo hInput('from_view', $view), '</td>';
    echo '<td valign="top" align="left" width="20">';
    //-- layer tabs -------------------
    echo $use_textile == 2 ? tab('text', $view) . tab('html', $view) . tab('preview', $view) : '&#160;';
    echo '</td>';
    ?>
	
<td width="200" valign="top" style="padding-left:10px" align="left" id="articleside">
<?php 
    //-- prev/next article links --
    if ($view == 'text') {
        if ($step != 'create' and ($prev_id or $next_id)) {
            echo '<p>', $prev_id ? prevnext_link('&#8249;' . gTxt('prev'), 'article', 'edit', $prev_id, gTxt('prev')) : '', $next_id ? prevnext_link(gTxt('next') . '&#8250;', 'article', 'edit', $next_id, gTxt('next')) : '', '</p>';
        }
    }
    //-- status radios --------------
    echo $view == 'text' ? n . graf(status_radio($Status)) . n : '';
    //-- category selects -----------
    echo $view == 'text' ? graf(gTxt('categorize') . ' [' . eLink('category', '', '', '', gTxt('edit')) . ']' . br . category_popup('Category1', $Category1) . category_popup('Category2', $Category2)) : '';
    //-- section select --------------
    if (!$from_view && !$pull) {
        $Section = getDefaultSection();
    }
    echo $view == 'text' ? graf(gTxt('section') . ' [' . eLink('section', '', '', '', gTxt('edit')) . ']' . br . section_popup($Section)) : '';
    //-- comments stuff --------------
    if ($step == "create") {
        //Avoiding invite disappear when previewing
        $AnnotateInvite = !empty($store_out['AnnotateInvite']) ? $store_out['AnnotateInvite'] : $comments_default_invite;
        if ($comments_on_default == 1) {
            $Annotate = 1;
        }
    }
    echo $use_comments == 1 && $view == 'text' ? graf(gTxt('comments') . onoffRadio("Annotate", $Annotate) . '<br />' . gTxt('comment_invitation') . '<br />' . fInput('text', 'AnnotateInvite', $AnnotateInvite, 'edit')) : '';
    //-- timestamp -------------------
    if ($step == "create" and empty($GLOBALS['ID'])) {
        if ($view == 'text') {
            //Avoiding modified date to disappear
            $persist_timestamp = !empty($store_out['year']) ? mktime($store_out['hour'], $store_out['minute'], '00', $store_out['month'], $store_out['day'], $store_out['year']) : time();
            echo graf(tag(checkbox('publish_now', '1') . gTxt('set_to_now'), 'label')), '<p>', gTxt('or_publish_at'), popHelp("timestamp"), br, tsi('year', 'Y', $persist_timestamp), tsi('month', 'm', $persist_timestamp), tsi('day', 'd', $persist_timestamp), sp, tsi('hour', 'H', $persist_timestamp), ':', tsi('minute', 'i', $persist_timestamp), '</p>';
        }
        //-- publish button --------------
        if ($view == 'text') {
            echo has_privs('article.publish') ? fInput('submit', 'publish', gTxt('publish'), "publish") : fInput('submit', 'publish', gTxt('save'), "publish");
        }
    } else {
        if ($view == 'text') {
            echo '<p>', gTxt('published_at'), popHelp("timestamp"), br, tsi('year', 'Y', $sPosted, 5), tsi('month', 'm', $sPosted, 6), tsi('day', 'd', $sPosted, 7), sp, tsi('hour', 'H', $sPosted, 8), ':', tsi('minute', 'i', $sPosted, 9), '</p>', hInput('sPosted', $sPosted), hInput('sLastMod', $sLastMod), hInput('AuthorID', $AuthorID), hInput('LastModID', $LastModID), graf(checkbox('reset_time', '1', 0) . gTxt('reset_time'));
        }
        //-- save button --------------
        if ($view == 'text') {
            if ($Status >= 4 and has_privs('article.edit.published') or $Status >= 4 and $AuthorID == $txp_user and has_privs('article.edit.own.published') or $Status < 4 and has_privs('article.edit') or $Status < 4 and $AuthorID == $txp_user and has_privs('article.edit.own')) {
                echo fInput('submit', 'save', gTxt('save'), "publish");
            }
        }
    }
    echo '</td></tr></table></form>';
}
Ejemplo n.º 3
0
/**
 * Renders article editor form.
 *
 * @param string|array $message          The activity message
 * @param bool         $concurrent       Treat as a concurrent save
 * @param bool         $refresh_partials Whether refresh partial contents
 */
function article_edit($message = '', $concurrent = false, $refresh_partials = false)
{
    global $vars, $txp_user, $prefs, $event, $view;
    extract($prefs);
    /*
    $partials is an array of:
    $key => array (
        'mode' => {PARTIAL_STATIC | PARTIAL_VOLATILE | PARTIAL_VOLATILE_VALUE},
        'selector' => $DOM_selector,
         'cb' => $callback_function,
         'html' => $return_value_of_callback_function (need not be intialised here)
    )
    */
    $partials = array('html_title' => array('mode' => PARTIAL_VOLATILE, 'selector' => 'title', 'cb' => 'article_partial_html_title'), 'sLastMod' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '[name=sLastMod]', 'cb' => 'article_partial_value'), 'sPosted' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '[name=sPosted]', 'cb' => 'article_partial_value'), 'sidehelp' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#textfilter_group', 'cb' => 'article_partial_sidehelp'), 'url_title' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.url-title', 'cb' => 'article_partial_url_title'), 'url_title_value' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '#url-title', 'cb' => 'article_partial_url_title_value'), 'description' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.description', 'cb' => 'article_partial_description'), 'description_value' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '#description', 'cb' => 'article_partial_description_value'), 'keywords' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.keywords', 'cb' => 'article_partial_keywords'), 'keywords_value' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '#keywords', 'cb' => 'article_partial_keywords_value'), 'image' => array('mode' => PARTIAL_STATIC, 'selector' => '#image_group', 'cb' => 'article_partial_image'), 'custom_fields' => array('mode' => PARTIAL_STATIC, 'selector' => '#custom_field_group', 'cb' => 'article_partial_custom_fields'), 'recent_articles' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#recent_group .recent', 'cb' => 'article_partial_recent_articles'), 'title' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.title', 'cb' => 'article_partial_title'), 'title_value' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '#title', 'cb' => 'article_partial_title_value'), 'article_clone' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#article_partial_article_clone', 'cb' => 'article_partial_article_clone'), 'article_view' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#article_partial_article_view', 'cb' => 'article_partial_article_view'), 'body' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.body', 'cb' => 'article_partial_body'), 'excerpt' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.excerpt', 'cb' => 'article_partial_excerpt'), 'author' => array('mode' => PARTIAL_VOLATILE, 'selector' => 'p.author', 'cb' => 'article_partial_author'), 'view_modes' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#view_modes', 'cb' => 'article_partial_view_modes'), 'article_nav' => array('mode' => PARTIAL_VOLATILE, 'selector' => 'p.nav-tertiary', 'cb' => 'article_partial_article_nav'), 'status' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#write-status', 'cb' => 'article_partial_status'), 'categories' => array('mode' => PARTIAL_STATIC, 'selector' => '#categories_group', 'cb' => 'article_partial_categories'), 'section' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.section', 'cb' => 'article_partial_section'), 'comments' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#write-comments', 'cb' => 'article_partial_comments'), 'posted' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#write-timestamp', 'cb' => 'article_partial_posted'), 'expires' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#write-expires', 'cb' => 'article_partial_expires'));
    // Add partials for custom fields (and their values which is redundant by
    // design, for plugins).
    global $cfs;
    foreach ($cfs as $k => $v) {
        $partials["custom_field_{$k}"] = array('mode' => PARTIAL_STATIC, 'selector' => "p.custom-field.custom-{$k}", 'cb' => 'article_partial_custom_field');
        $partials["custom_{$k}"] = array('mode' => PARTIAL_STATIC, 'selector' => "#custom-{$k}", 'cb' => 'article_partial_value');
    }
    extract(gpsa(array('view', 'from_view', 'step')));
    // Newly-saved article.
    if (!empty($GLOBALS['ID'])) {
        $ID = $GLOBALS['ID'];
        $step = 'edit';
    } else {
        $ID = gps('ID');
    }
    // Switch to 'text' view upon page load and after article post.
    if (!$view || gps('save') || gps('publish')) {
        $view = 'text';
    }
    if (!$step) {
        $step = "create";
    }
    if ($step == "edit" && $view == "text" && !empty($ID) && $from_view != 'preview' && $from_view != 'html' && !$concurrent) {
        $pull = true;
        // It's an existing article - off we go to the database.
        $ID = assert_int($ID);
        $rs = safe_row("*, UNIX_TIMESTAMP(Posted) AS sPosted,\n            UNIX_TIMESTAMP(Expires) AS sExpires,\n            UNIX_TIMESTAMP(LastMod) AS sLastMod", 'textpattern', "ID = {$ID}");
        if (empty($rs)) {
            return;
        }
        $rs['reset_time'] = $rs['publish_now'] = false;
    } else {
        $pull = false;
        // Assume they came from post.
        if ($from_view == 'preview' or $from_view == 'html') {
            $store_out = array();
            $store = unserialize(base64_decode(ps('store')));
            foreach ($vars as $var) {
                if (isset($store[$var])) {
                    $store_out[$var] = $store[$var];
                }
            }
        } else {
            $store_out = gpsa($vars);
            if ($concurrent) {
                $store_out['sLastMod'] = safe_field("UNIX_TIMESTAMP(LastMod) AS sLastMod", 'textpattern', "ID = {$ID}");
            }
            if (!has_privs('article.set_markup') && !empty($ID)) {
                $oldArticle = safe_row("textile_body, textile_excerpt", 'textpattern', "ID = {$ID}");
                if (!empty($oldArticle)) {
                    $store_out['textile_body'] = $oldArticle['textile_body'];
                    $store_out['textile_excerpt'] = $oldArticle['textile_excerpt'];
                }
            }
        }
        // Use preferred Textfilter as default and fallback.
        $hasfilter = new \Textpattern\Textfilter\Constraint(null);
        $validator = new Validator();
        foreach (array('textile_body', 'textile_excerpt') as $k) {
            $hasfilter->setValue($store_out[$k]);
            $validator->setConstraints($hasfilter);
            if (!$validator->validate()) {
                $store_out[$k] = $use_textile;
            }
        }
        $rs = textile_main_fields($store_out);
        if (!empty($rs['exp_year'])) {
            if (empty($rs['exp_month'])) {
                $rs['exp_month'] = 1;
            }
            if (empty($rs['exp_day'])) {
                $rs['exp_day'] = 1;
            }
            if (empty($rs['exp_hour'])) {
                $rs['exp_hour'] = 0;
            }
            if (empty($rs['exp_minute'])) {
                $rs['exp_minute'] = 0;
            }
            if (empty($rs['exp_second'])) {
                $rs['exp_second'] = 0;
            }
            $rs['sExpires'] = safe_strtotime($rs['exp_year'] . '-' . $rs['exp_month'] . '-' . $rs['exp_day'] . ' ' . $rs['exp_hour'] . ':' . $rs['exp_minute'] . ':' . $rs['exp_second']);
        }
        if (!empty($rs['year'])) {
            $rs['sPosted'] = safe_strtotime($rs['year'] . '-' . $rs['month'] . '-' . $rs['day'] . ' ' . $rs['hour'] . ':' . $rs['minute'] . ':' . $rs['second']);
        }
    }
    $validator = new Validator(new SectionConstraint($rs['Section']));
    if (!$validator->validate()) {
        $rs['Section'] = getDefaultSection();
    }
    extract($rs);
    $GLOBALS['step'] = $step;
    if ($step != 'create' && isset($sPosted)) {
        // Previous record?
        $rs['prev_id'] = checkIfNeighbour('prev', $sPosted);
        // Next record?
        $rs['next_id'] = checkIfNeighbour('next', $sPosted);
    } else {
        $rs['prev_id'] = $rs['next_id'] = 0;
    }
    // Let plugins chime in on partials meta data.
    callback_event_ref('article_ui', 'partials_meta', 0, $rs, $partials);
    $rs['partials_meta'] =& $partials;
    // Get content for volatile partials.
    foreach ($partials as $k => $p) {
        if ($p['mode'] == PARTIAL_VOLATILE || $p['mode'] == PARTIAL_VOLATILE_VALUE) {
            $cb = $p['cb'];
            $partials[$k]['html'] = is_array($cb) ? call_user_func($cb, $rs, $k) : $cb($rs, $k);
        }
    }
    if ($refresh_partials) {
        $response[] = announce($message);
        $response[] = '$("#article_form [type=submit]").val(textpattern.gTxt("save"))';
        if ($Status < STATUS_LIVE) {
            $response[] = '$("#article_form").addClass("saved").removeClass("published")';
        } else {
            $response[] = '$("#article_form").addClass("published").removeClass("saved")';
        }
        // Update the volatile partials.
        foreach ($partials as $k => $p) {
            // Volatile partials need a target DOM selector.
            if (empty($p['selector']) && $p['mode'] != PARTIAL_STATIC) {
                trigger_error("Empty selector for partial '{$k}'", E_USER_ERROR);
            } else {
                // Build response script.
                if ($p['mode'] == PARTIAL_VOLATILE) {
                    // Volatile partials replace *all* of the existing HTML
                    // fragment for their selector.
                    $response[] = '$("' . $p['selector'] . '").replaceWith("' . escape_js($p['html']) . '")';
                } elseif ($p['mode'] == PARTIAL_VOLATILE_VALUE) {
                    // Volatile partial values replace the *value* of elements
                    // matching their selector.
                    $response[] = '$("' . $p['selector'] . '").val("' . escape_js($p['html']) . '")';
                }
            }
        }
        send_script_response(join(";\n", $response));
        // Bail out.
        return;
    }
    foreach ($partials as $k => $p) {
        if ($p['mode'] == PARTIAL_STATIC) {
            $cb = $p['cb'];
            $partials[$k]['html'] = is_array($cb) ? call_user_func($cb, $rs, $k) : $cb($rs, $k);
        }
    }
    $page_title = $ID ? $Title : gTxt('write');
    pagetop($page_title, $message);
    $class = array();
    if ($Status >= STATUS_LIVE) {
        $class[] = 'published';
    } elseif ($ID) {
        $class[] = 'saved';
    }
    if ($step !== 'create') {
        $class[] = 'async';
    }
    echo n . tag_start('form', array('class' => $class, 'id' => 'article_form', 'name' => 'article_form', 'method' => 'post', 'action' => 'index.php'));
    if (!empty($store_out)) {
        echo hInput('store', base64_encode(serialize($store_out)));
    }
    echo hInput('ID', $ID) . eInput('article') . sInput($step) . hInput('sPosted', $sPosted) . hInput('sLastMod', $sLastMod) . hInput('AuthorID', $AuthorID) . hInput('LastModID', $LastModID) . n . '<input type="hidden" name="view" />';
    echo n . '<div class="txp-layout-4col-cell-1-2-3">' . hed(gTxt('tab_write'), 1, array('class' => 'txp-heading'));
    echo n . '<div role="region" id="main_content">';
    // View mode tabs.
    echo $partials['view_modes']['html'];
    // Title input.
    if ($view == 'preview') {
        echo n . '<div class="preview">' . graf(gTxt('title'), array('class' => 'alert-block information')) . hed($Title, 1, ' class="title"');
    } elseif ($view == 'html') {
        echo n . '<div class="html">' . graf(gTxt('title'), array('class' => 'alert-block information')) . hed($Title, 1, ' class="title"');
    } elseif ($view == 'text') {
        echo n . '<div class="text">' . $partials['title']['html'];
    }
    // Body.
    if ($view == 'preview') {
        echo n . '<div class="body">' . n . graf(gTxt('body'), array('class' => 'alert-block information')) . $Body_html . '</div>';
    } elseif ($view == 'html') {
        echo graf(gTxt('body'), array('class' => 'alert-block information')) . n . tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), txpspecialchars($Body_html)), 'pre', ' class="body"');
    } else {
        echo $partials['body']['html'];
    }
    // Excerpt.
    if ($articles_use_excerpts) {
        if ($view == 'preview') {
            echo n . '<div class="excerpt">' . graf(gTxt('excerpt'), array('class' => 'alert-block information')) . $Excerpt_html . '</div>';
        } elseif ($view == 'html') {
            echo graf(gTxt('excerpt'), array('class' => 'alert-block information')) . n . tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), txpspecialchars($Excerpt_html)), 'pre', array('class' => 'excerpt'));
        } else {
            echo $partials['excerpt']['html'];
        }
    }
    echo hInput('from_view', $view), n . '</div>';
    // Author.
    if ($view == "text" && $step != "create") {
        echo $partials['author']['html'];
    }
    echo n . '</div>' . n . '</div>';
    // End of .txp-layout-4col-cell-1-2-3.
    // Sidebar column (only shown if in text editing view).
    if ($view == 'text') {
        echo n . '<div class="txp-layout-4col-cell-4alt">';
        // 'Publish/Save' button.
        if ($step == 'create' and empty($GLOBALS['ID'])) {
            if (has_privs('article.publish')) {
                $push_button = fInput('submit', 'publish', gTxt('publish'), 'publish');
            } else {
                $push_button = fInput('submit', 'publish', gTxt('save'), 'publish');
            }
            echo graf($push_button, array('class' => 'txp-save'));
        } elseif ($Status >= STATUS_LIVE && has_privs('article.edit.published') || $Status >= STATUS_LIVE && $AuthorID === $txp_user && has_privs('article.edit.own.published') || $Status < STATUS_LIVE && has_privs('article.edit') || $Status < STATUS_LIVE && $AuthorID === $txp_user && has_privs('article.edit.own')) {
            echo graf(fInput('submit', 'save', gTxt('save'), 'publish'), array('class' => 'txp-save'));
        }
        // View/Duplicate/Create new article links.
        $an_cb = href('<span class="ui-icon ui-extra-icon-new-document"></span> ' . gTxt('create_new'), 'index.php?event=article', array('class' => 'txp-new'));
        $ac_cb = $rs['partials_meta']['article_clone']['cb'];
        $av_cb = $rs['partials_meta']['article_view']['cb'];
        echo $step != 'create' ? graf($an_cb . $ac_cb($rs) . $av_cb($rs), array('class' => 'txp-actions')) : '';
        // Prev/next article links.
        if ($step != 'create' and ($rs['prev_id'] or $rs['next_id'])) {
            echo $partials['article_nav']['html'];
        }
        echo n . '<div role="region" id="supporting_content">';
        // 'Sort and display' section.
        echo pluggable_ui('article_ui', 'sort_display', wrapRegion('txp-write-sort-group', $partials['status']['html'] . $partials['section']['html'] . $partials['categories']['html'], '', gTxt('sort_display')), $rs);
        // 'Date and time' collapsible section.
        if ($step == "create" and empty($GLOBALS['ID'])) {
            // Timestamp.
            // Avoiding modified date to disappear.
            if (!empty($store_out['year'])) {
                $persist_timestamp = safe_strtotime($store_out['year'] . '-' . $store_out['month'] . '-' . $store_out['day'] . ' ' . $store_out['hour'] . ':' . $store_out['minute'] . ':' . $store_out['second']);
            } else {
                $persist_timestamp = time();
            }
            $posted_block = pluggable_ui('article_ui', 'timestamp', inputLabel('year', tsi('year', '%Y', $persist_timestamp, '', 'year') . ' <span role="separator">/</span> ' . tsi('month', '%m', $persist_timestamp, '', 'month') . ' <span role="separator">/</span> ' . tsi('day', '%d', $persist_timestamp, '', 'day'), 'publish_date', array('timestamp', 'instructions_publish_date'), array('class' => 'txp-form-field date posted')) . inputLabel('hour', tsi('hour', '%H', $persist_timestamp, '', 'hour') . ' <span role="separator">:</span> ' . tsi('minute', '%M', $persist_timestamp, '', 'minute') . ' <span role="separator">:</span> ' . tsi('second', '%S', $persist_timestamp, '', 'second'), 'publish_time', array('', 'instructions_publish_time'), array('class' => 'txp-form-field time posted')) . n . tag(checkbox('publish_now', '1', $publish_now, '', 'publish_now') . n . tag(gTxt('set_to_now'), 'label', array('for' => 'publish_now')), 'div', array('class' => 'posted-now')), array('sPosted' => $persist_timestamp) + $rs);
            // Expires.
            if (!empty($store_out['exp_year'])) {
                $persist_timestamp = safe_strtotime($store_out['exp_year'] . '-' . $store_out['exp_month'] . '-' . $store_out['exp_day'] . ' ' . $store_out['exp_hour'] . ':' . $store_out['exp_minute'] . ':' . $store_out['second']);
            } else {
                $persist_timestamp = 0;
            }
            $expires_block = pluggable_ui('article_ui', 'expires', inputLabel('exp_year', tsi('exp_year', '%Y', $persist_timestamp, '', 'exp_year') . ' <span role="separator">/</span> ' . tsi('exp_month', '%m', $persist_timestamp, '', 'exp_month') . ' <span role="separator">/</span> ' . tsi('exp_day', '%d', $persist_timestamp, '', 'exp_day'), 'expire_date', array('expires', 'instructions_expire_date'), array('class' => 'txp-form-field date expires')) . inputLabel('exp_hour', tsi('exp_hour', '%H', $persist_timestamp, '', 'exp_hour') . ' <span role="separator">:</span> ' . tsi('exp_minute', '%M', $persist_timestamp, '', 'exp_minute') . ' <span role="separator">:</span> ' . tsi('exp_second', '%S', $persist_timestamp, '', 'exp_second'), 'expire_time', array('', 'instructions_expire_time'), array('class' => 'txp-form-field time expires')), $rs);
        } else {
            // Timestamp.
            $posted_block = $partials['posted']['html'];
            // Expires.
            $expires_block = $partials['expires']['html'];
        }
        echo wrapRegion('txp-dates-group', $posted_block . $expires_block, 'txp-dates-group-content', 'date_settings', 'article_dates');
        // 'Meta' collapsible section.
        // 'URL-only title' field.
        $html_url_title = $partials['url_title']['html'];
        // 'Description' field.
        $html_description = $partials['description']['html'];
        // 'Keywords' field.
        $html_keywords = $partials['keywords']['html'];
        echo wrapRegion('txp-meta-group', $html_url_title . $html_description . $html_keywords, 'txp-meta-group-content', 'meta', 'article_meta');
        // 'Comment options' collapsible section.
        echo wrapRegion('txp-comments-group', $partials['comments']['html'], 'txp-comments-group-content', 'comment_settings', 'article_comments', $use_comments == 1 ? '' : 'empty');
        // 'Article image' collapsible section.
        echo $partials['image']['html'];
        // 'Custom fields' collapsible section.
        echo $partials['custom_fields']['html'];
        // 'Advanced options' collapsible section.
        // 'Article markup'/'Excerpt markup' selection.
        if (has_privs('article.set_markup')) {
            $html_markup = inputLabel('markup-body', pref_text('textile_body', $textile_body, 'markup-body'), 'article_markup', array('', 'instructions_textile_body'), array('class' => 'txp-form-field markup markup-body')) . inputLabel('markup-excerpt', pref_text('textile_excerpt', $textile_excerpt, 'markup-excerpt'), 'excerpt_markup', array('', 'instructions_textile_excerpt'), array('class' => 'txp-form-field markup markup-excerpt'));
        } else {
            $html_markup = '';
        }
        $html_markup = pluggable_ui('article_ui', 'markup', $html_markup, $rs);
        // 'Override form' selection.
        $form_pop = $allow_form_override ? form_pop($override_form, 'override-form') : '';
        $html_override = $form_pop ? pluggable_ui('article_ui', 'override', inputLabel('override-form', $form_pop, 'override_default_form', array('override_form', 'instructions_override_form'), array('class' => 'txp-form-field override-form')), $rs) : '';
        echo wrapRegion('txp-advanced-group', $html_markup . $html_override, 'txp-advanced-group-content', 'advanced_options', 'article_advanced');
        // Custom menu entries.
        echo pluggable_ui('article_ui', 'extend_col_1', '', $rs);
        // 'Text formatting help' collapsible section.
        echo $partials['sidehelp']['html'];
        // 'Recent articles' collapsible section.
        echo wrapRegion('txp-recent-group', $partials['recent_articles']['html'], 'txp-recent-group-content', 'recent_articles', 'article_recent');
        echo n . '</div>';
        // End of #supporting_content.
        echo n . '</div>';
        // End of .txp-layout-4col-cell-4alt.
    }
    echo tInput() . n . '</form>';
}
Ejemplo n.º 4
0
function article_edit($message = '', $concurrent = FALSE)
{
    global $vars, $txp_user, $comments_disabled_after, $txpcfg, $prefs, $event;
    extract($prefs);
    extract(gpsa(array('view', 'from_view', 'step')));
    if (!empty($GLOBALS['ID'])) {
        // newly-saved article
        $ID = $GLOBALS['ID'];
        $step = 'edit';
    } else {
        $ID = gps('ID');
    }
    include_once txpath . '/lib/classTextile.php';
    $textile = new Textile();
    // switch to 'text' view upon page load and after article post
    if (!$view || gps('save') || gps('publish')) {
        $view = 'text';
    }
    if (!$step) {
        $step = "create";
    }
    if ($step == "edit" && $view == "text" && !empty($ID) && $from_view != 'preview' && $from_view != 'html' && !$concurrent) {
        $pull = true;
        //-- it's an existing article - off we go to the db
        $ID = assert_int($ID);
        $rs = safe_row("*, unix_timestamp(Posted) as sPosted,\n\t\t\t\tunix_timestamp(Expires) as sExpires,\n\t\t\t\tunix_timestamp(LastMod) as sLastMod", "textpattern", "ID={$ID}");
        extract($rs);
        $reset_time = $publish_now = $Status < 4 && $sPosted <= time();
    } else {
        $pull = false;
        //-- assume they came from post
        if ($from_view == 'preview' or $from_view == 'html') {
            $store_out = array();
            $store = unserialize(base64_decode(ps('store')));
            foreach ($vars as $var) {
                if (isset($store[$var])) {
                    $store_out[$var] = $store[$var];
                }
            }
        } else {
            $store_out = gpsa($vars);
            if ($concurrent) {
                $store_out['sLastMod'] = safe_field('unix_timestamp(LastMod) as sLastMod', 'textpattern', 'ID=' . $ID);
            }
        }
        $rs = $store_out;
        extract($store_out);
    }
    $GLOBALS['step'] = $step;
    if ($step == 'create') {
        $textile_body = $use_textile;
        $textile_excerpt = $use_textile;
    }
    if ($step != 'create' && $sPosted) {
        // Previous record?
        $prev_id = checkIfNeighbour('prev', $sPosted);
        // Next record?
        $next_id = checkIfNeighbour('next', $sPosted);
    } else {
        $prev_id = $next_id = 0;
    }
    $page_title = $Title ? $Title : gTxt('write');
    pagetop($page_title, $message);
    echo n . '<div id="' . $event . '_container" class="txp-container txp-edit">';
    echo n . n . '<form id="article_form" name="article_form" method="post" action="index.php">';
    if (!empty($store_out)) {
        echo hInput('store', base64_encode(serialize($store_out)));
    }
    echo hInput('ID', $ID) . eInput('article') . sInput($step) . '<input type="hidden" name="view" />' . startTable('edit') . '<tr>' . n . '<td id="article-col-1"><div id="configuration_content">';
    if ($view == 'text') {
        //-- markup help --------------
        echo pluggable_ui('article_ui', 'sidehelp', side_help($textile_body, $textile_excerpt), $rs);
        //-- custom menu entries --------------
        echo pluggable_ui('article_ui', 'extend_col_1', '', $rs);
        //-- advanced --------------
        echo '<div id="advanced_group"><h3 class="plain lever' . (get_pref('pane_article_advanced_visible') ? ' expanded' : '') . '"><a href="#advanced">' . gTxt('advanced_options') . '</a></h3>' . '<div id="advanced" class="toggle" style="display:' . (get_pref('pane_article_advanced_visible') ? 'block' : 'none') . '">';
        // markup selection
        echo pluggable_ui('article_ui', 'markup', n . graf('<label for="markup-body">' . gTxt('article_markup') . '</label>' . br . pref_text('textile_body', $textile_body, 'markup-body'), ' class="markup markup-body"') . n . graf('<label for="markup-excerpt">' . gTxt('excerpt_markup') . '</label>' . br . pref_text('textile_excerpt', $textile_excerpt, 'markup-excerpt'), ' class="markup markup-excerpt"'), $rs);
        // form override
        echo $allow_form_override ? pluggable_ui('article_ui', 'override', graf('<label for="override-form">' . gTxt('override_default_form') . '</label>' . sp . popHelp('override_form') . br . form_pop($override_form, 'override-form'), ' class="override-form"'), $rs) : '';
        echo '</div></div>' . n;
        //-- custom fields --------------
        $cf = '';
        $cfs = getCustomFields();
        echo '<div id="custom_field_group"' . ($cfs ? '' : ' class="empty"') . '><h3 class="plain lever' . (get_pref('pane_article_custom_field_visible') ? ' expanded' : '') . '"><a href="#custom_field">' . gTxt('custom') . '</a></h3>' . '<div id="custom_field" class="toggle" style="display:' . (get_pref('pane_article_custom_field_visible') ? 'block' : 'none') . '">';
        foreach ($cfs as $i => $cf_name) {
            $custom_x_set = "custom_{$i}_set";
            $custom_x = "custom_{$i}";
            $cf .= ${$custom_x_set} !== '' ? custField($i, ${$custom_x_set}, ${$custom_x}) : '';
        }
        echo pluggable_ui('article_ui', 'custom_fields', $cf, $rs);
        echo '</div></div>' . n;
        //-- article image --------------
        echo '<div id="image_group"><h3 class="plain lever' . (get_pref('pane_article_image_visible') ? ' expanded' : '') . '"><a href="#image">' . gTxt('article_image') . '</a></h3>' . '<div id="image" class="toggle" style="display:' . (get_pref('pane_article_image_visible') ? 'block' : 'none') . '">';
        echo pluggable_ui('article_ui', 'article_image', n . graf('<label for="article-image">' . gTxt('article_image') . '</label>' . sp . popHelp('article_image') . br . fInput('text', 'Image', $Image, 'edit', '', '', 22, '', 'article-image'), ' class="article-image"'), $rs);
        echo '</div></div>' . n;
        //-- meta info --------------
        echo '<div id="meta_group"><h3 class="plain lever' . (get_pref('pane_article_meta_visible') ? ' expanded' : '') . '"><a href="#meta">' . gTxt('meta') . '</a></h3>' . '<div id="meta" class="toggle" style="display:' . (get_pref('pane_article_meta_visible') ? 'block' : 'none') . '">';
        // keywords
        echo pluggable_ui('article_ui', 'keywords', n . graf('<label for="keywords">' . gTxt('keywords') . '</label>' . sp . popHelp('keywords') . br . n . '<textarea id="keywords" name="Keywords" cols="18" rows="5">' . htmlspecialchars(str_replace(',', ', ', $Keywords)) . '</textarea>', ' class="keywords"'), $rs);
        // url title
        echo pluggable_ui('article_ui', 'url_title', n . graf('<label for="url-title">' . gTxt('url_title') . '</label>' . sp . popHelp('url_title') . br . fInput('text', 'url_title', $url_title, 'edit', '', '', 22, '', 'url-title'), ' class="url-title"'), $rs);
        echo '</div></div>' . n;
        //-- recent articles --------------
        echo '<div id="recent_group"><h3 class="plain lever' . (get_pref('pane_article_recent_visible') ? ' expanded' : '') . '"><a href="#recent">' . gTxt('recent_articles') . '</a>' . '</h3>' . '<div id="recent" class="toggle" style="display:' . (get_pref('pane_article_recent_visible') ? 'block' : 'none') . '">';
        $recents = safe_rows_start("Title, ID", 'textpattern', "1=1 order by LastMod desc limit 10");
        $ra = '';
        if ($recents) {
            $ra = '<ul class="recent plain-list">';
            while ($recent = nextRow($recents)) {
                if (!$recent['Title']) {
                    $recent['Title'] = gTxt('untitled') . sp . $recent['ID'];
                }
                $ra .= n . t . '<li class="recent-article"><a href="?event=article' . a . 'step=edit' . a . 'ID=' . $recent['ID'] . '">' . escape_title($recent['Title']) . '</a></li>';
            }
            $ra .= '</ul>';
        }
        echo pluggable_ui('article_ui', 'recent_articles', $ra, $rs);
        echo '</div></div>';
    } else {
        echo sp;
    }
    echo '</div></td>' . n . '<td id="article-main"><div id="main_content">';
    //-- title input --------------
    if ($view == 'preview') {
        echo '<div class="preview">' . hed(gTxt('preview'), 2) . hed($Title, 1, ' class="title"');
    } elseif ($view == 'html') {
        echo '<div class="xhtml">' . hed('XHTML', 2) . hed($Title, 1, ' class="title"');
    } elseif ($view == 'text') {
        echo '<div class="text">' . pluggable_ui('article_ui', 'title', n . '<p class="title"><label for="title">' . gTxt('title') . '</label>' . sp . popHelp('title') . br . '<input type="text" id="title" name="Title" value="' . escape_title($Title) . '" class="edit" size="40" tabindex="1" />', $rs);
        if ($step != 'create') {
            if ($Status != 4 and $Status != 5) {
                $url = '?txpreview=' . intval($ID) . '.' . time();
                // article ID plus cachebuster
            } else {
                include_once txpath . '/publish/taghandlers.php';
                $url = permlinkurl_id($ID);
            }
            echo sp . sp . '<a href="' . $url . '" class="article-view">' . gTxt('view') . '</a>';
        }
        echo '</p>';
    }
    //-- body --------------------
    if ($view == 'preview') {
        echo '<div class="body">';
        if ($textile_body == USE_TEXTILE) {
            echo $textile->TextileThis($Body);
        } else {
            if ($textile_body == CONVERT_LINEBREAKS) {
                echo nl2br($Body);
            } else {
                if ($textile_body == LEAVE_TEXT_UNTOUCHED) {
                    echo $Body;
                }
            }
        }
        echo '</div>';
    } elseif ($view == 'html') {
        if ($textile_body == USE_TEXTILE) {
            $bod = $textile->TextileThis($Body);
        } else {
            if ($textile_body == CONVERT_LINEBREAKS) {
                $bod = nl2br($Body);
            } else {
                if ($textile_body == LEAVE_TEXT_UNTOUCHED) {
                    $bod = $Body;
                }
            }
        }
        echo tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), htmlspecialchars($bod)), 'code', ' class="body"');
    } else {
        echo pluggable_ui('article_ui', 'body', n . graf('<label for="body">' . gTxt('body') . '</label>' . sp . popHelp('body') . br . '<textarea id="body" name="Body" cols="55" rows="31" tabindex="2">' . htmlspecialchars($Body) . '</textarea>', ' class="body"'), $rs);
    }
    //-- excerpt --------------------
    if ($articles_use_excerpts) {
        if ($view == 'text') {
            echo pluggable_ui('article_ui', 'excerpt', n . graf('<label for="excerpt">' . gTxt('excerpt') . '</label>' . sp . popHelp('excerpt') . br . '<textarea id="excerpt" name="Excerpt" cols="55" rows="5" tabindex="3">' . htmlspecialchars($Excerpt) . '</textarea>', ' class="excerpt"'), $rs);
        } else {
            echo n . '<hr width="50%" />';
            echo '<div class="excerpt">';
            echo $textile_excerpt == USE_TEXTILE ? $view == 'preview' ? graf($textile->textileThis($Excerpt)) : tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), htmlspecialchars($textile->TextileThis($Excerpt))), 'code', ' class="excerpt"') : graf($Excerpt);
            echo '</div>';
        }
    }
    //-- author --------------
    if ($view == "text" && $step != "create") {
        echo '<p class="author small">' . gTxt('posted_by') . ': ' . htmlspecialchars($AuthorID) . ' &#183; ' . safe_strftime('%d %b %Y &#183; %X', $sPosted);
        if ($sPosted != $sLastMod) {
            echo br . gTxt('modified_by') . ': ' . htmlspecialchars($LastModID) . ' &#183; ' . safe_strftime('%d %b %Y &#183; %X', $sLastMod);
        }
        echo '</p>';
    }
    echo hInput('from_view', $view), '</div></div></td>';
    //-- layer tabs -------------------
    echo '<td id="article-tabs"><div id="view_modes">';
    echo pluggable_ui('article_ui', 'view', $use_textile == USE_TEXTILE || $textile_body == USE_TEXTILE ? tag(tab('text', $view) . tab('html', $view) . tab('preview', $view), 'ul') : '&#160;', $rs);
    echo '</div></td>';
    echo '<td id="article-col-2"><div id="supporting_content">';
    if ($view == 'text') {
        if ($step != 'create') {
            echo n . graf(href(gtxt('create_new'), 'index.php?event=article'), ' class="action-create"');
        }
        //-- prev/next article links --
        if ($step != 'create' and ($prev_id or $next_id)) {
            echo '<p class="article-nav">', $prev_id ? prevnext_link('&#8249;' . gTxt('prev'), 'article', 'edit', $prev_id, gTxt('prev')) : '', $next_id ? prevnext_link(gTxt('next') . '&#8250;', 'article', 'edit', $next_id, gTxt('next')) : '', '</p>';
        }
        //-- status radios --------------
        echo pluggable_ui('article_ui', 'status', n . n . '<fieldset id="write-status">' . n . '<legend>' . gTxt('status') . '</legend>' . n . status_radio($Status) . n . '</fieldset>', $rs);
        //-- category selects -----------
        echo pluggable_ui('article_ui', 'categories', n . n . '<fieldset id="write-sort">' . n . '<legend>' . gTxt('sort_display') . '</legend>' . n . graf('<label for="category-1">' . gTxt('category1') . '</label> ' . '<span class="edit category-edit small">[' . eLink('category', '', '', '', gTxt('edit')) . ']</span>' . br . n . category_popup('Category1', $Category1, 'category-1'), ' class="category category-1"') . n . graf('<label for="category-2">' . gTxt('category2') . '</label>' . br . n . category_popup('Category2', $Category2, 'category-2'), ' class="category category-2"'), $rs);
        //-- section select --------------
        if (!$from_view && !$pull) {
            $Section = getDefaultSection();
        }
        echo pluggable_ui('article_ui', 'section', n . graf('<label for="section">' . gTxt('section') . '</label> ' . '<span class="edit section-edit small">[' . eLink('section', '', '', '', gTxt('edit')) . ']</span>' . br . section_popup($Section, 'section'), ' class="section"') . n . '</fieldset>', $rs);
        //-- "More" section
        echo n . n . '<div id="more_group"><h3 class="plain lever' . (get_pref('pane_article_more_visible') ? ' expanded' : '') . '"><a href="#more">' . gTxt('more') . '</a></h3>', '<div id="more" class="toggle" style="display:' . (get_pref('pane_article_more_visible') ? 'block' : 'none') . '">';
        //-- comments stuff --------------
        if ($step == "create") {
            //Avoiding invite disappear when previewing
            $AnnotateInvite = !empty($store_out['AnnotateInvite']) ? $store_out['AnnotateInvite'] : $comments_default_invite;
            if ($comments_on_default == 1) {
                $Annotate = 1;
            }
        }
        if ($use_comments == 1) {
            $invite[] = n . n . '<fieldset id="write-comments">' . n . '<legend>' . gTxt('comments') . '</legend>';
            $comments_expired = false;
            if ($step != 'create' && $comments_disabled_after) {
                $lifespan = $comments_disabled_after * 86400;
                $time_since = time() - $sPosted;
                if ($time_since > $lifespan) {
                    $comments_expired = true;
                }
            }
            if ($comments_expired) {
                $invite[] = n . n . graf(gTxt('expired'), ' class="comment-annotate"');
            } else {
                $invite[] = n . n . graf(onoffRadio('Annotate', $Annotate), ' class="comment-annotate"') . n . n . graf('<label for="comment-invite">' . gTxt('comment_invitation') . '</label>' . br . fInput('text', 'AnnotateInvite', $AnnotateInvite, 'edit', '', '', '', '', 'comment-invite'), ' class="comment-invite"');
            }
            $invite[] = n . n . '</fieldset>';
            echo pluggable_ui('article_ui', 'annotate_invite', join('', $invite), $rs);
        }
        if ($step == "create" and empty($GLOBALS['ID'])) {
            //-- timestamp -------------------
            //Avoiding modified date to disappear
            $persist_timestamp = !empty($store_out['year']) ? safe_strtotime($store_out['year'] . '-' . $store_out['month'] . '-' . $store_out['day'] . ' ' . $store_out['hour'] . ':' . $store_out['minute'] . ':' . $store_out['second']) : time();
            echo pluggable_ui('article_ui', 'timestamp', n . n . '<fieldset id="write-timestamp">' . n . '<legend>' . gTxt('timestamp') . '</legend>' . n . graf(checkbox('publish_now', '1', $publish_now, '', 'publish_now') . '<label for="publish_now">' . gTxt('set_to_now') . '</label>', ' class="publish-now"') . n . graf(gTxt('or_publish_at') . sp . popHelp('timestamp'), ' class="publish-at"') . n . graf('<span class="label">' . gtxt('date') . '</span>' . sp . tsi('year', '%Y', $persist_timestamp) . ' / ' . tsi('month', '%m', $persist_timestamp) . ' / ' . tsi('day', '%d', $persist_timestamp), ' class="date posted created"') . n . graf('<span class="label">' . gTxt('time') . '</span>' . sp . tsi('hour', '%H', $persist_timestamp) . ' : ' . tsi('minute', '%M', $persist_timestamp) . ' : ' . tsi('second', '%S', $persist_timestamp), ' class="time posted created"') . n . '</fieldset>', array('sPosted' => $persist_timestamp) + $rs);
            //-- expires -------------------
            $persist_timestamp = !empty($store_out['exp_year']) ? safe_strtotime($store_out['exp_year'] . '-' . $store_out['exp_month'] . '-' . $store_out['exp_day'] . ' ' . $store_out['exp_hour'] . ':' . $store_out['exp_minute'] . ':' . $store_out['second']) : NULLDATETIME;
            echo pluggable_ui('article_ui', 'expires', n . n . '<fieldset id="write-expires">' . n . '<legend>' . gTxt('expires') . '</legend>' . n . graf('<span class="label">' . gtxt('date') . '</span>' . sp . tsi('exp_year', '%Y', $persist_timestamp) . ' / ' . tsi('exp_month', '%m', $persist_timestamp) . ' / ' . tsi('exp_day', '%d', $persist_timestamp), ' class="date expires"') . n . graf('<span class="label">' . gTxt('time') . '</span>' . sp . tsi('exp_hour', '%H', $persist_timestamp) . ' : ' . tsi('exp_minute', '%M', $persist_timestamp) . ' : ' . tsi('exp_second', '%S', $persist_timestamp), ' class="time expires"') . n . '</fieldset>', $rs);
            // end "More" section
            echo n . n . '</div></div>';
            //-- publish button --------------
            echo has_privs('article.publish') ? fInput('submit', 'publish', gTxt('publish'), "publish", '', '', '', 4) : fInput('submit', 'publish', gTxt('save'), "publish", '', '', '', 4);
        } else {
            //-- timestamp -------------------
            if (!empty($year)) {
                $sPosted = safe_strtotime($year . '-' . $month . '-' . $day . ' ' . $hour . ':' . $minute . ':' . $second);
            }
            echo pluggable_ui('article_ui', 'timestamp', n . n . '<fieldset id="write-timestamp">' . n . '<legend>' . gTxt('timestamp') . '</legend>' . n . graf(checkbox('reset_time', '1', $reset_time, '', 'reset_time') . '<label for="reset_time">' . gTxt('reset_time') . '</label>', ' class="reset-time"') . n . graf(gTxt('published_at') . sp . popHelp('timestamp'), ' class="publish-at"') . n . graf('<span class="label">' . gtxt('date') . '</span>' . sp . tsi('year', '%Y', $sPosted) . ' / ' . tsi('month', '%m', $sPosted) . ' / ' . tsi('day', '%d', $sPosted), ' class="date posted created"') . n . graf('<span class="label">' . gTxt('time') . '</span>' . sp . tsi('hour', '%H', $sPosted) . ' : ' . tsi('minute', '%M', $sPosted) . ' : ' . tsi('second', '%S', $sPosted), ' class="time posted created"') . n . hInput('sPosted', $sPosted) . n . hInput('sLastMod', $sLastMod) . n . hInput('AuthorID', $AuthorID) . n . hInput('LastModID', $LastModID) . n . '</fieldset>', $rs);
            //-- expires -------------------
            if (!empty($exp_year)) {
                if (empty($exp_month)) {
                    $exp_month = 1;
                }
                if (empty($exp_day)) {
                    $exp_day = 1;
                }
                if (empty($exp_hour)) {
                    $exp_hour = 0;
                }
                if (empty($exp_minute)) {
                    $exp_minute = 0;
                }
                if (empty($exp_second)) {
                    $exp_second = 0;
                }
                $sExpires = safe_strtotime($exp_year . '-' . $exp_month . '-' . $exp_day . ' ' . $exp_hour . ':' . $exp_minute . ':' . $exp_second);
            }
            echo pluggable_ui('article_ui', 'expires', n . n . '<fieldset id="write-expires">' . n . '<legend>' . gTxt('expires') . '</legend>' . n . graf('<span class="label">' . gtxt('date') . '</span>' . sp . tsi('exp_year', '%Y', $sExpires) . ' / ' . tsi('exp_month', '%m', $sExpires) . ' / ' . tsi('exp_day', '%d', $sExpires), ' class="date expires"') . n . graf('<span class="label">' . gTxt('time') . '</span>' . sp . tsi('exp_hour', '%H', $sExpires) . ' : ' . tsi('exp_minute', '%M', $sExpires) . ' : ' . tsi('exp_second', '%S', $sExpires), ' class="time expires"') . n . hInput('sExpires', $sExpires) . n . '</fieldset>', $rs);
            // end "More" section
            echo n . n . '</div></div>';
            //-- save button --------------
            if ($Status >= 4 and has_privs('article.edit.published') or $Status >= 4 and $AuthorID == $txp_user and has_privs('article.edit.own.published') or $Status < 4 and has_privs('article.edit') or $Status < 4 and $AuthorID == $txp_user and has_privs('article.edit.own')) {
                echo fInput('submit', 'save', gTxt('save'), "publish", '', '', '', 4);
            }
        }
    }
    echo '</div></td></tr></table></form></div>' . n;
    // Assume users would not change the timestamp if they wanted to "publish now"/"reset time"
    echo script_js(<<<EOS
\t\t\$('#write-timestamp input.edit').change(
\t\t\tfunction() {
\t\t\t\t\$('#publish_now').attr('checked', false);
\t\t\t\t\$('#reset_time').attr('checked', false);
\t\t\t});
EOS
);
}
Ejemplo n.º 5
0
function article_edit_form($step, $view, $from_view, $article)
{
    global $txpcfg, $txp_user, $article_vars;
    extract(get_prefs());
    extract($article);
    if ($step != 'create') {
        // Previous record?
        $prev_id = checkIfNeighbour('prev', $sPosted);
        // Next record?
        $next_id = checkIfNeighbour('next', $sPosted);
    }
    echo n . n . '<form name="article" method="post" action="index.php" enctype="multipart/form-data">';
    if ($view != 'text') {
        echo hInput('store', base64_encode(serialize($article)));
    }
    echo hInput('ID', $ID) . eInput('article') . sInput($step) . '<input type="hidden" name="view" />' . startTable('edit') . '<tr>' . n . '<td id="article-col-1">';
    if ($view == 'text') {
        //-- markup help --------------
        echo side_help($markup_body, $markup_excerpt) . '<h3 class="plain"><a href="#advanced" onclick="toggleDisplay(\'advanced\'); return false;">' . gTxt('advanced_options') . '</a></h3>', '<div id="advanced" style="display:none;">', n . graf('<label for="markup-body">' . gTxt('article_markup') . '</label>' . br . pref_markup('markup_body', $markup_body, 'markup-body')), n . graf('<label for="markup-excerpt">' . gTxt('excerpt_markup') . '</label>' . pref_markup('markup_excerpt', $markup_excerpt, 'markup-excerpt')), $allow_form_override ? graf('<label for="override-form">' . gTxt('override_default_form') . '</label>' . br . form_pop($override_form, 'override-form') . sp . popHelp('override_form')) : '', n . graf('<label for="article-image">' . gTxt('article_image') . '</label>' . sp . popHelp('article_image') . br . fInput('text', 'Image', $Image, 'edit', '', '', 22, '', 'article-image')), n . graf('<label for="url-title">' . gTxt('url_title') . '</label>' . sp . popHelp('url_title') . br . fInput('text', 'url_title', $url_title, 'edit', '', '', 22, '', 'url-title')) . '</div>

			<h3 class="plain"><a href="#recent" onclick="toggleDisplay(\'recent\'); return false;">' . gTxt('recent_articles') . '</a>' . '</h3>' . '<div id="recent" style="display:none;">';
        $recents = safe_rows_start("Title, ID", 'textpattern', "1=1 order by LastMod desc limit 10");
        if ($recents) {
            echo '<ul class="plain-list">';
            while ($recent = nextRow($recents)) {
                if (!$recent['Title']) {
                    $recent['Title'] = gTxt('untitled') . sp . $recent['ID'];
                }
                echo n . t . '<li><a href="?event=article' . a . 'step=edit' . a . 'ID=' . $recent['ID'] . '">' . escape_title($recent['Title']) . '</a></li>';
            }
            echo '</ul>';
        }
        echo '</div>';
    } else {
        echo sp;
    }
    echo '</td>' . n . '<td id="article-main">';
    //-- title input --------------
    if ($view == 'preview') {
        echo hed(gTxt('preview'), 2) . hed($Title, 1);
    } elseif ($view == 'html') {
        echo hed('XHTML', 2) . hed($Title, 1);
    } else {
        echo '<p><label for="title">' . gTxt('title') . '</label>';
        if (($Status == 4 or $Status == 5) and $step != 'create') {
            include_once txpath . '/publish/taghandlers.php';
            echo sp . sp . '[<a href="' . permlinkurl_id($ID) . '">' . gTxt('view') . '</a>]';
        }
        echo '<br />' . n . '<input type="text" id="title" name="Title" value="' . cleanfInput($Title) . '" class="edit" size="65" tabindex="1" /></p>';
    }
    //-- body --------------------
    if ($view == 'preview') {
        echo do_markup($markup_body, $Body);
    } elseif ($view == 'html') {
        $bod = do_markup($markup_body, $Body);
        echo tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), htmlspecialchars($bod)), 'code');
    } else {
        echo n . graf('<label for="body">' . gTxt('body') . '</label><br />' . n . '<textarea id="body" name="Body" cols="55" rows="31" tabindex="2">' . htmlspecialchars($Body) . '</textarea>');
    }
    //-- excerpt --------------------
    if ($articles_use_excerpts) {
        if ($view == 'text') {
            echo n . graf('<label for="excerpt">' . gTxt('excerpt') . '</label>' . sp . popHelp('excerpt') . br . '<textarea id="excerpt" name="Excerpt" cols="55" rows="10" tabindex="3">' . htmlspecialchars($Excerpt) . '</textarea>');
        } else {
            echo n . '<hr width="50%" />';
            echo $view == 'preview' ? graf(do_markup($markup_excerpt, $Excerpt)) : tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), htmlspecialchars(do_markup($markup_excerpt, $Excerpt))), 'code');
        }
    }
    //-- keywords --------------
    if ($view == 'text') {
        echo n . graf('<label for="keywords">' . gTxt('keywords') . '</label>' . sp . popHelp('keywords') . br . '<textarea id="keywords" name="Keywords" cols="55" rows="5">' . htmlspecialchars(str_replace(',', ', ', $Keywords)) . '</textarea>');
        //-- custom fields --------------
        echo $custom_1_set ? custField(1, $custom_1_set, $custom_1) : '', $custom_2_set ? custField(2, $custom_2_set, $custom_2) : '', $custom_3_set ? custField(3, $custom_3_set, $custom_3) : '', $custom_4_set ? custField(4, $custom_4_set, $custom_4) : '', $custom_5_set ? custField(5, $custom_5_set, $custom_5) : '', $custom_6_set ? custField(6, $custom_6_set, $custom_6) : '', $custom_7_set ? custField(7, $custom_7_set, $custom_7) : '', $custom_8_set ? custField(8, $custom_8_set, $custom_8) : '', $custom_9_set ? custField(9, $custom_9_set, $custom_9) : '', $custom_10_set ? custField(10, $custom_10_set, $custom_10) : '';
    }
    //-- author --------------
    if ($view == "text" && $step != "create") {
        echo '<p class="small">' . gTxt('posted_by') . ': ' . htmlspecialchars($AuthorID) . ' &#183; ' . safe_strftime('%d %b %Y &#183; %X', $sPosted);
        if ($sPosted != $sLastMod) {
            echo br . gTxt('modified_by') . ': ' . htmlspecialchars($LastModID) . ' &#183; ' . safe_strftime('%d %b %Y &#183; %X', $sLastMod);
        }
        echo '</p>';
    }
    echo hInput('from_view', $view);
    echo '</td>';
    echo '<td id="article-tabs">';
    //-- layer tabs -------------------
    echo graf(tab('text', $view) . br . tab('html', $view) . br . tab('preview', $view));
    echo '</td>';
    echo '<td id="article-col-2">';
    if ($view == 'text') {
        if ($step != 'create') {
            echo n . graf(href(gtxt('create_new'), 'index.php?event=article'));
        }
        //-- prev/next article links --
        if ($step != 'create' and ($prev_id or $next_id)) {
            echo '<p>', $prev_id ? prevnext_link('&#8249;' . gTxt('prev'), 'article', 'edit', $prev_id, gTxt('prev')) : '', $next_id ? prevnext_link(gTxt('next') . '&#8250;', 'article', 'edit', $next_id, gTxt('next')) : '', '</p>';
        }
        //-- status radios --------------
        echo n . n . fieldset(status_radio($Status), gTxt('status'), 'write-status') . n . n . fieldset(n . graf('<label for="section">' . gTxt('section') . '</label> ' . '<span class="small">[' . eLink('section', '', '', '', gTxt('edit')) . ']</span>' . br . section_popup($Section, 'section')) . n . graf('<label for="category-1">' . gTxt('category1') . '</label> ' . '<span class="small">[' . eLink('category', '', '', '', gTxt('edit')) . ']</span>' . br . n . category_popup('Category1', $Category1, 'category-1')) . n . graf('<label for="category-2">' . gTxt('category2') . '</label>' . br . n . category_popup('Category2', $Category2, 'category-2')), gTxt('sort_display'), 'write-sort') . n . n . '<h3 class="plain"><a href="#more" onclick="toggleDisplay(\'more\'); return false;">' . gTxt('more') . '</a></h3>', '<div id="more" style="display: none;">';
        //-- comments stuff --------------
        if ($step == "create") {
            //Avoiding invite disappear when previewing
            $AnnotateInvite = !empty($store_out['AnnotateInvite']) ? $store_out['AnnotateInvite'] : $comments_default_invite;
            if ($comments_on_default == 1) {
                $Annotate = 1;
            }
        }
        if ($use_comments == 1) {
            echo n . n . '<fieldset id="write-comments">' . n . '<legend>' . gTxt('comments') . '</legend>';
            $comments_expired = false;
            if ($step != 'create' && $comments_disabled_after) {
                $lifespan = $comments_disabled_after * 86400;
                $time_since = time() - $sPosted;
                if ($time_since > $lifespan) {
                    $comments_expired = true;
                }
            }
            if ($comments_expired) {
                echo n . n . graf(gTxt('expired'));
            } else {
                echo n . n . graf(onoffRadio('Annotate', $Annotate)) . n . n . graf('<label for="comment-invite">' . gTxt('comment_invitation') . '</label>' . br . fInput('text', 'AnnotateInvite', $AnnotateInvite, 'edit', '', '', '', '', 'comment-invite'));
            }
            echo n . n . '</fieldset>';
        }
        if ($step == "create" and empty($GLOBALS['ID'])) {
            //-- timestamp -------------------
            //Avoiding modified date to disappear
            $persist_timestamp = !empty($store_out['year']) ? safe_strtotime($store_out['year'] . '-' . $store_out['month'] . '-' . $store_out['day'] . ' ' . $store_out['hour'] . ':' . $store_out['minute'] . ':' . $store_out['second']) : time();
            echo n . n . fieldset(n . graf(checkbox('publish_now', '1', $publish_now, '', 'publish_now') . '<label for="publish_now">' . gTxt('set_to_now') . '</label>') . n . graf(gTxt('or_publish_at') . sp . popHelp('timestamp')) . n . graf(gtxt('date') . sp . tsi('year', '%Y', $persist_timestamp, '', 4) . ' / ' . tsi('month', '%m', $persist_timestamp) . ' / ' . tsi('day', '%d', $persist_timestamp)) . n . graf(gTxt('time') . sp . tsi('hour', '%H', $persist_timestamp) . ' : ' . tsi('minute', '%M', $persist_timestamp) . ' : ' . tsi('second', '%S', $persist_timestamp)), gTxt('timestamp'), 'write-timestamp');
            //-- expires -------------------
            $persist_timestamp = !empty($store_out['exp_year']) ? safe_strtotime($store_out['exp_year'] . '-' . $store_out['exp_month'] . '-' . $store_out['exp_day'] . ' ' . $store_out['exp_hour'] . ':' . $store_out['exp_minute'] . ':' . $store_out['second']) : NULLDATETIME;
            echo n . n . fieldset(n . graf(gtxt('date') . sp . tsi('exp_year', '%Y', $persist_timestamp, '', 4) . ' / ' . tsi('exp_month', '%m', $persist_timestamp) . ' / ' . tsi('exp_day', '%d', $persist_timestamp)) . n . graf(gTxt('time') . sp . tsi('exp_hour', '%H', $persist_timestamp) . ' : ' . tsi('exp_minute', '%M', $persist_timestamp) . ' : ' . tsi('exp_second', '%S', $persist_timestamp)), gTxt('expires') . sp . popHelp('expires'), 'write-expires') . n . n . '</div>';
            //-- publish button --------------
            echo has_privs('article.publish') ? fInput('submit', 'publish', gTxt('publish'), "publish", '', '', '', 4) : fInput('submit', 'publish', gTxt('save'), "publish", '', '', '', 4);
        } else {
            //-- timestamp -------------------
            if (!empty($year)) {
                $sPosted = safe_strtotime($year . '-' . $month . '-' . $day . ' ' . $hour . ':' . $minute . ':' . $second);
            }
            echo n . n . fieldset(n . graf(checkbox('reset_time', '1', $reset_time, '', 'reset_time') . '<label for="reset_time">' . gTxt('reset_time') . '</label>') . n . graf(gTxt('published_at') . sp . popHelp('timestamp')) . n . graf(gtxt('date') . sp . tsi('year', '%Y', $sPosted, '', 4) . ' / ' . tsi('month', '%m', $sPosted) . ' / ' . tsi('day', '%d', $sPosted)) . n . graf(gTxt('time') . sp . tsi('hour', '%H', $sPosted) . ' : ' . tsi('minute', '%M', $sPosted) . ' : ' . tsi('second', '%S', $sPosted)) . n . hInput('sPosted', $sPosted) . n . hInput('sLastMod', $sLastMod) . n . hInput('AuthorID', $AuthorID) . n . hInput('LastModID', $LastModID), gTxt('timestamp'), 'write-timestamp');
            //-- expires -------------------
            if (!empty($exp_year)) {
                if (empty($exp_month)) {
                    $exp_month = 1;
                }
                if (empty($exp_day)) {
                    $exp_day = 1;
                }
                if (empty($exp_hour)) {
                    $exp_hour = 0;
                }
                if (empty($exp_minute)) {
                    $exp_minute = 0;
                }
                if (empty($exp_second)) {
                    $exp_second = 0;
                }
                $sExpires = safe_strtotime($exp_year . '-' . $exp_month . '-' . $exp_day . ' ' . $exp_hour . ':' . $exp_minute . ':' . $exp_second);
            }
            echo n . n . fieldset(n . graf(gtxt('date') . sp . tsi('exp_year', '%Y', $sExpires, '', 4) . ' / ' . tsi('exp_month', '%m', $sExpires) . ' / ' . tsi('exp_day', '%d', $sExpires)) . n . graf(gTxt('time') . sp . tsi('exp_hour', '%H', $sExpires) . ' : ' . tsi('exp_minute', '%M', $sExpires) . ' : ' . tsi('exp_second', '%S', $sExpires)) . n . hInput('sExpires', $sExpires), gTxt('expires') . sp . popHelp('expires'), 'write-expires') . n . n . '</div>';
            //-- save button --------------
            if ($Status >= 4 and has_privs('article.edit.published') or $Status >= 4 and $AuthorID == $txp_user and has_privs('article.edit.own.published') or $Status < 4 and has_privs('article.edit') or $Status < 4 and $AuthorID == $txp_user and has_privs('article.edit.own')) {
                echo fInput('submit', 'save', gTxt('save'), "publish", '', '', '', 4);
            }
        }
    }
    echo '</td></tr></table></form>';
}
Ejemplo n.º 6
0
function article_edit($message = '', $concurrent = FALSE, $refresh_partials = FALSE)
{
    global $vars, $txp_user, $prefs, $event;
    extract($prefs);
    /*
    $partials is an array of:
    $key => array (
    	'mode' => {PARTIAL_STATIC | PARTIAL_VOLATILE | PARTIAL_VOLATILE_VALUE},
    	'selector' => $DOM_selector,
     	'cb' => $callback_function,
     	'html' => $return_value_of_callback_function (need not be intialized here)
    )
    */
    $partials = array('sLastMod' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '[name=sLastMod]', 'cb' => 'article_partial_value'), 'sPosted' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '[name=sPosted]', 'cb' => 'article_partial_value'), 'custom_fields' => array('mode' => PARTIAL_STATIC, 'selector' => '#custom_field_group', 'cb' => 'article_partial_custom_fields'), 'image' => array('mode' => PARTIAL_STATIC, 'selector' => '#image_group', 'cb' => 'article_partial_image'), 'keywords' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.keywords', 'cb' => 'article_partial_keywords'), 'keywords_value' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '#keywords', 'cb' => 'article_partial_keywords_value'), 'url_title' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.url-title', 'cb' => 'article_partial_url_title'), 'url_title_value' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '#url-title', 'cb' => 'article_partial_url_title_value'), 'recent_articles' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#recent_group .recent', 'cb' => 'article_partial_recent_articles'), 'title' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.title', 'cb' => 'article_partial_title'), 'title_value' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '#title', 'cb' => 'article_partial_title_value'), 'article_view' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#article_partial_article_view', 'cb' => 'article_partial_article_view'), 'body' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.body', 'cb' => 'article_partial_body'), 'excerpt' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.excerpt', 'cb' => 'article_partial_excerpt'), 'author' => array('mode' => PARTIAL_VOLATILE, 'selector' => 'p.author', 'cb' => 'article_partial_author'), 'article_nav' => array('mode' => PARTIAL_VOLATILE, 'selector' => 'p.nav-tertiary', 'cb' => 'article_partial_article_nav'), 'status' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#write-status', 'cb' => 'article_partial_status'), 'categories' => array('mode' => PARTIAL_STATIC, 'selector' => '#categories_group', 'cb' => 'article_partial_categories'), 'section' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.section', 'cb' => 'article_partial_section'), 'comments' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#write-comments', 'cb' => 'article_partial_comments'), 'posted' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#write-timestamp', 'cb' => 'article_partial_posted'), 'expires' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#write-expires', 'cb' => 'article_partial_expires'));
    // add partials for custom fields (and their values which is redundant by design, for plugins)
    global $cfs;
    foreach ($cfs as $k => $v) {
        $partials["custom_field_{$k}"] = array('mode' => PARTIAL_STATIC, 'selector' => "p.custom-field.custom-{$k}", 'cb' => 'article_partial_custom_field');
        $partials["custom_{$k}"] = array('mode' => PARTIAL_STATIC, 'selector' => "#custom-{$k}", 'cb' => 'article_partial_value');
    }
    extract(gpsa(array('view', 'from_view', 'step')));
    if (!empty($GLOBALS['ID'])) {
        // newly-saved article
        $ID = $GLOBALS['ID'];
        $step = 'edit';
    } else {
        $ID = gps('ID');
    }
    // switch to 'text' view upon page load and after article post
    if (!$view || gps('save') || gps('publish')) {
        $view = 'text';
    }
    if (!$step) {
        $step = "create";
    }
    if ($step == "edit" && $view == "text" && !empty($ID) && $from_view != 'preview' && $from_view != 'html' && !$concurrent) {
        $pull = true;
        //-- it's an existing article - off we go to the db
        $ID = assert_int($ID);
        $rs = safe_row("*, unix_timestamp(Posted) as sPosted,\n\t\t\t\tunix_timestamp(Expires) as sExpires,\n\t\t\t\tunix_timestamp(LastMod) as sLastMod", "textpattern", "ID={$ID}");
        if (empty($rs)) {
            return;
        }
        $rs['reset_time'] = $rs['publish_now'] = false;
    } else {
        $pull = false;
        //-- assume they came from post
        if ($from_view == 'preview' or $from_view == 'html') {
            $store_out = array();
            $store = unserialize(base64_decode(ps('store')));
            foreach ($vars as $var) {
                if (isset($store[$var])) {
                    $store_out[$var] = $store[$var];
                }
            }
        } else {
            $store_out = gpsa($vars);
            if ($concurrent) {
                $store_out['sLastMod'] = safe_field('unix_timestamp(LastMod) as sLastMod', 'textpattern', 'ID=' . $ID);
            }
        }
        $rs = textile_main_fields($store_out);
        if (!empty($rs['exp_year'])) {
            if (empty($rs['exp_month'])) {
                $rs['exp_month'] = 1;
            }
            if (empty($rs['exp_day'])) {
                $rs['exp_day'] = 1;
            }
            if (empty($rs['exp_hour'])) {
                $rs['exp_hour'] = 0;
            }
            if (empty($rs['exp_minute'])) {
                $rs['exp_minute'] = 0;
            }
            if (empty($rs['exp_second'])) {
                $rs['exp_second'] = 0;
            }
            $rs['sExpires'] = safe_strtotime($rs['exp_year'] . '-' . $rs['exp_month'] . '-' . $rs['exp_day'] . ' ' . $rs['exp_hour'] . ':' . $rs['exp_minute'] . ':' . $rs['exp_second']);
        }
        if (!empty($rs['year'])) {
            $rs['sPosted'] = safe_strtotime($rs['year'] . '-' . $rs['month'] . '-' . $rs['day'] . ' ' . $rs['hour'] . ':' . $rs['minute'] . ':' . $rs['second']);
        }
    }
    $validator = new Validator(array(new SectionConstraint($rs['Section'])));
    if (!$validator->validate()) {
        $rs['Section'] = getDefaultSection();
    }
    extract($rs);
    $GLOBALS['step'] = $step;
    if ($step == 'create') {
        $textile_body = $use_textile;
        $textile_excerpt = $use_textile;
    }
    if ($step != 'create' && isset($sPosted)) {
        // Previous record?
        $rs['prev_id'] = checkIfNeighbour('prev', $sPosted);
        // Next record?
        $rs['next_id'] = checkIfNeighbour('next', $sPosted);
    } else {
        $rs['prev_id'] = $rs['next_id'] = 0;
    }
    // let plugins chime in on partials meta data
    callback_event_ref('article_ui', 'partials_meta', 0, $rs, $partials);
    $rs['partials_meta'] =& $partials;
    // get content for volatile partials
    foreach ($partials as $k => $p) {
        if ($p['mode'] == PARTIAL_VOLATILE || $p['mode'] == PARTIAL_VOLATILE_VALUE) {
            $cb = $p['cb'];
            $partials[$k]['html'] = is_array($cb) ? call_user_func($cb, $rs, $k) : $cb($rs, $k);
        }
    }
    if ($refresh_partials) {
        global $theme;
        $response[] = $theme->announce_async($message);
        // update the volatile partials
        foreach ($partials as $k => $p) {
            // volatile partials need a target DOM selector
            if (empty($p['selector']) && $p['mode'] != PARTIAL_STATIC) {
                trigger_error("Empty selector for partial '{$k}'", E_USER_ERROR);
            } else {
                // build response script
                if ($p['mode'] == PARTIAL_VOLATILE) {
                    // volatile partials replace *all* of the existing HTML fragment for their selector
                    $response[] = '$("' . $p['selector'] . '").replaceWith("' . escape_js($p['html']) . '")';
                } elseif ($p['mode'] == PARTIAL_VOLATILE_VALUE) {
                    // volatile partial values replace the *value* of elements matching their selector
                    $response[] = '$("' . $p['selector'] . '").val("' . escape_js($p['html']) . '")';
                }
            }
        }
        send_script_response(join(";\n", $response));
        // bail out
        return;
    }
    foreach ($partials as $k => $p) {
        if ($p['mode'] == PARTIAL_STATIC) {
            $cb = $p['cb'];
            $partials[$k]['html'] = is_array($cb) ? call_user_func($cb, $rs, $k) : $cb($rs, $k);
        }
    }
    $page_title = $Title ? $Title : gTxt('write');
    pagetop($page_title, $message);
    echo n . '<div id="' . $event . '_container" class="txp-container">';
    echo n . n . '<form id="article_form" name="article_form" method="post" action="index.php" ' . ($step == 'create' ? '>' : ' class="async">');
    if (!empty($store_out)) {
        echo hInput('store', base64_encode(serialize($store_out)));
    }
    echo hInput('ID', $ID) . n . eInput('article') . n . sInput($step) . n . hInput('sPosted', $sPosted) . n . hInput('sLastMod', $sLastMod) . n . hInput('AuthorID', $AuthorID) . n . hInput('LastModID', $LastModID) . '<input type="hidden" name="view" />' . startTable('', '', 'txp-columntable') . '<tr>' . n . '<td id="article-col-1"><div id="configuration_content">';
    if ($view == 'text') {
        //-- markup help --------------
        echo pluggable_ui('article_ui', 'sidehelp', side_help($textile_body, $textile_excerpt), $rs);
        //-- custom menu entries --------------
        echo pluggable_ui('article_ui', 'extend_col_1', '', $rs);
        //-- advanced --------------
        echo '<div id="advanced_group"><h3 class="lever' . (get_pref('pane_article_advanced_visible') ? ' expanded' : '') . '"><a href="#advanced">' . gTxt('advanced_options') . '</a></h3>' . '<div id="advanced" class="toggle" style="display:' . (get_pref('pane_article_advanced_visible') ? 'block' : 'none') . '">';
        // markup selection
        echo pluggable_ui('article_ui', 'markup', n . graf('<label for="markup-body">' . gTxt('article_markup') . '</label>' . br . pref_text('textile_body', $textile_body, 'markup-body'), ' class="markup markup-body"') . n . graf('<label for="markup-excerpt">' . gTxt('excerpt_markup') . '</label>' . br . pref_text('textile_excerpt', $textile_excerpt, 'markup-excerpt'), ' class="markup markup-excerpt"'), $rs);
        // form override
        echo $allow_form_override ? pluggable_ui('article_ui', 'override', graf('<label for="override-form">' . gTxt('override_default_form') . '</label>' . sp . popHelp('override_form') . br . form_pop($override_form, 'override-form'), ' class="override-form"'), $rs) : '';
        echo '</div></div>' . n;
        //-- custom fields --------------
        echo $partials['custom_fields']['html'];
        //-- article image --------------
        echo $partials['image']['html'];
        //-- meta info --------------
        echo '<div id="meta_group"><h3 class="lever' . (get_pref('pane_article_meta_visible') ? ' expanded' : '') . '"><a href="#meta">' . gTxt('meta') . '</a></h3>' . '<div id="meta" class="toggle" style="display:' . (get_pref('pane_article_meta_visible') ? 'block' : 'none') . '">';
        // keywords
        echo $partials['keywords']['html'];
        // url title
        echo $partials['url_title']['html'];
        echo '</div></div>' . n;
        //-- recent articles --------------
        echo '<div id="recent_group"><h3 class="lever' . (get_pref('pane_article_recent_visible') ? ' expanded' : '') . '"><a href="#recent">' . gTxt('recent_articles') . '</a>' . '</h3>' . '<div id="recent" class="toggle" style="display:' . (get_pref('pane_article_recent_visible') ? 'block' : 'none') . '">';
        echo $partials['recent_articles']['html'];
        echo '</div></div>';
    } else {
        echo sp;
    }
    echo '</div></td>' . n . '<td id="article-main"><div id="main_content">';
    //-- title input --------------
    if ($view == 'preview') {
        echo '<div class="preview">' . hed(gTxt('preview'), 2) . hed($Title, 1, ' class="title"');
    } elseif ($view == 'html') {
        echo '<div class="html">' . hed('HTML', 2) . hed($Title, 1, ' class="title"');
    } elseif ($view == 'text') {
        echo '<div class="text">' . n . $partials['title']['html'];
    }
    //-- body --------------------
    if ($view == 'preview') {
        echo '<div class="body">' . $Body_html . '</div>';
    } elseif ($view == 'html') {
        echo tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), txpspecialchars($Body_html)), 'code', ' class="body"');
    } else {
        echo $partials['body']['html'];
    }
    //-- excerpt --------------------
    if ($articles_use_excerpts) {
        if ($view == 'preview') {
            echo n . '<hr /><div class="excerpt">' . $Excerpt_html . '</div>';
        } elseif ($view == 'html') {
            echo n . '<hr />' . tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), txpspecialchars($Excerpt_html)), 'code', ' class="excerpt"');
        } else {
            echo $partials['excerpt']['html'];
        }
    }
    //-- author --------------
    if ($view == "text" && $step != "create") {
        echo $partials['author']['html'];
    }
    echo hInput('from_view', $view), '</div></div></td>';
    //-- layer tabs -------------------
    echo '<td id="article-tabs"><div id="view_modes">';
    echo pluggable_ui('article_ui', 'view', $use_textile == USE_TEXTILE || $textile_body == USE_TEXTILE ? tag(tab('text', $view) . tab('html', $view) . tab('preview', $view), 'ul') : '&#160;', $rs);
    echo '</div></td>';
    echo '<td id="article-col-2"><div id="supporting_content">';
    if ($view == 'text') {
        if ($step != 'create') {
            echo n . graf(href(gtxt('create_new'), 'index.php?event=article'), ' class="action-create"');
        }
        //-- prev/next article links --
        if ($step != 'create' and ($rs['prev_id'] or $rs['next_id'])) {
            echo $partials['article_nav']['html'];
        }
        //-- status radios --------------
        echo $partials['status']['html'];
        //-- sort and display  -----------
        echo pluggable_ui('article_ui', 'sort_display', n . n . tag(n . '<legend>' . gTxt('sort_display') . '</legend>' . $partials['section']['html'] . $partials['categories']['html'] . n, 'fieldset', ' id="write-sort"'), $rs);
        //-- "Comments" section
        echo n . n . '<div id="comments_group"' . ($use_comments == 1 ? '' : ' class="empty"') . '><h3 class="lever' . (get_pref('pane_article_comments_visible') ? ' expanded' : '') . '"><a href="#comments">' . gTxt('comment_settings') . '</a></h3>', '<div id="comments" class="toggle" style="display:' . (get_pref('pane_article_comments_visible') ? 'block' : 'none') . '">';
        echo $partials['comments']['html'];
        // end "Comments" section
        echo '</div></div>';
        //-- "Dates" section
        echo n . n . '<div id="dates_group"><h3 class="lever' . (get_pref('pane_article_dates_visible') ? ' expanded' : '') . '"><a href="#dates">' . gTxt('date_settings') . '</a></h3>', '<div id="dates" class="toggle" style="display:' . (get_pref('pane_article_dates_visible') ? 'block' : 'none') . '">';
        if ($step == "create" and empty($GLOBALS['ID'])) {
            //-- timestamp -------------------
            //Avoiding modified date to disappear
            $persist_timestamp = !empty($store_out['year']) ? safe_strtotime($store_out['year'] . '-' . $store_out['month'] . '-' . $store_out['day'] . ' ' . $store_out['hour'] . ':' . $store_out['minute'] . ':' . $store_out['second']) : time();
            echo pluggable_ui('article_ui', 'timestamp', n . n . '<fieldset id="write-timestamp">' . n . '<legend>' . gTxt('timestamp') . '</legend>' . n . graf(checkbox('publish_now', '1', $publish_now, '', 'publish_now') . '<label for="publish_now">' . gTxt('set_to_now') . '</label>', ' class="publish-now"') . n . graf(gTxt('or_publish_at') . sp . popHelp('timestamp'), ' class="publish-at"') . n . graf('<span class="label">' . gtxt('date') . '</span>' . sp . tsi('year', '%Y', $persist_timestamp) . ' / ' . tsi('month', '%m', $persist_timestamp) . ' / ' . tsi('day', '%d', $persist_timestamp), ' class="date posted created"') . n . graf('<span class="label">' . gTxt('time') . '</span>' . sp . tsi('hour', '%H', $persist_timestamp) . ' : ' . tsi('minute', '%M', $persist_timestamp) . ' : ' . tsi('second', '%S', $persist_timestamp), ' class="time posted created"') . n . '</fieldset>', array('sPosted' => $persist_timestamp) + $rs);
            //-- expires -------------------
            $persist_timestamp = !empty($store_out['exp_year']) ? safe_strtotime($store_out['exp_year'] . '-' . $store_out['exp_month'] . '-' . $store_out['exp_day'] . ' ' . $store_out['exp_hour'] . ':' . $store_out['exp_minute'] . ':' . $store_out['second']) : NULLDATETIME;
            echo pluggable_ui('article_ui', 'expires', n . n . '<fieldset id="write-expires">' . n . '<legend>' . gTxt('expires') . '</legend>' . n . graf('<span class="label">' . gtxt('date') . '</span>' . sp . tsi('exp_year', '%Y', $persist_timestamp) . ' / ' . tsi('exp_month', '%m', $persist_timestamp) . ' / ' . tsi('exp_day', '%d', $persist_timestamp), ' class="date expires"') . n . graf('<span class="label">' . gTxt('time') . '</span>' . sp . tsi('exp_hour', '%H', $persist_timestamp) . ' : ' . tsi('exp_minute', '%M', $persist_timestamp) . ' : ' . tsi('exp_second', '%S', $persist_timestamp), ' class="time expires"') . n . '</fieldset>', $rs);
            // end "Dates" section
            echo n . n . '</div></div>';
            //-- publish button --------------
            echo graf(has_privs('article.publish') ? fInput('submit', 'publish', gTxt('publish'), "publish", '', '', '', 4) : fInput('submit', 'publish', gTxt('save'), "publish", '', '', '', 4), ' id="write-publish"');
        } else {
            //-- timestamp -------------------
            echo $partials['posted']['html'];
            //-- expires -------------------
            echo $partials['expires']['html'];
            // end "Dates" section
            echo n . n . '</div></div>';
            //-- save button --------------
            if ($Status >= STATUS_LIVE and has_privs('article.edit.published') or $Status >= STATUS_LIVE and $AuthorID == $txp_user and has_privs('article.edit.own.published') or $Status < STATUS_LIVE and has_privs('article.edit') or $Status < STATUS_LIVE and $AuthorID == $txp_user and has_privs('article.edit.own')) {
                echo graf(fInput('submit', 'save', gTxt('save'), "publish", '', '', '', 4), ' id="write-save"');
            }
        }
    }
    echo '</div></td></tr></table>' . n . tInput() . n . '</form></div>' . n;
    // Assume users would not change the timestamp if they wanted to "publish now"/"reset time"
    echo script_js(<<<EOS
\t\t\$('#write-timestamp input.year,#write-timestamp input.month,#write-timestamp input.day,#write-timestamp input.hour,#write-timestamp input.minute,#write-timestamp input.second').change(
\t\t\tfunction() {
\t\t\t\t\$('#publish_now').prop('checked', false);
\t\t\t\t\$('#reset_time').prop('checked', false);
\t\t\t});
EOS
);
}