gTxt('draft'), 2 => gTxt('hidden'), 3 => gTxt('pending'), 4 => strong(gTxt('live')), 5 => gTxt('sticky'), ); if (!empty($event) and $event == 'article') { require_privs('article'); $save = gps('save'); if ($save) $step = 'save'; $publish = gps('publish'); if ($publish) $step = 'publish'; switch(strtolower($step)) { case "": article_edit(); break; case "create": article_edit(); break; case "publish": article_post(); break; case "edit": article_edit(); break; case "save": article_save(); break; } } //-------------------------------------------------------------- function article_post() { global $txp_user, $vars, $txpcfg, $prefs; extract($prefs); $incoming = psa($vars); $message=''; $incoming = textile_main_fields($incoming, $use_textile); extract(doSlash($incoming)); extract(array_map('assert_int', psa(array( 'Status', 'textile_body', 'textile_excerpt')))); $Annotate = (int) $Annotate; if ($publish_now==1) { $when = 'now()'; $when_ts = time(); } else { $when = $when_ts = strtotime($year.'-'.$month.'-'.$day.' '.$hour.':'.$minute.':'.$second)-tz_offset(); $when = "from_unixtime($when)"; } $Keywords = doSlash(trim(preg_replace('/( ?[\r\n\t,])+ ?/s', ',', preg_replace('/ +/', ' ', ps('Keywords'))), ', ')); if (empty($exp_year)) { $expires = 0; $whenexpires = NULLDATETIME; } else { 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; $expires = strtotime($exp_year.'-'.$exp_month.'-'.$exp_day.' '. $exp_hour.':'.$exp_minute.':'.$exp_second)-tz_offset(); $whenexpires = "from_unixtime($expires)"; } if ($expires) { if ($expires <= $when_ts) { article_edit(gTxt('article_expires_before_postdate')); return; } } if ($Title or $Body or $Excerpt) { if (!has_privs('article.publish') && $Status>=4) $Status = 3; if (empty($url_title)) $url_title = stripSpace($Title_plain, 1); safe_insert( "textpattern", "Title = '$Title', Body = '$Body', Body_html = '$Body_html', Excerpt = '$Excerpt', Excerpt_html = '$Excerpt_html', Image = '$Image', Keywords = '$Keywords', Status = $Status, Posted = $when, Expires = $whenexpires, LastMod = now(), AuthorID = '$txp_user', Section = '$Section', Category1 = '$Category1', Category2 = '$Category2', textile_body = $textile_body, textile_excerpt = $textile_excerpt, Annotate = $Annotate, override_form = '$override_form', url_title = '$url_title', AnnotateInvite = '$AnnotateInvite', custom_1 = '$custom_1', custom_2 = '$custom_2', custom_3 = '$custom_3', custom_4 = '$custom_4', custom_5 = '$custom_5', custom_6 = '$custom_6', custom_7 = '$custom_7', custom_8 = '$custom_8', custom_9 = '$custom_9', custom_10 = '$custom_10', uid = '".md5(uniqid(rand(),true))."', feed_time = now()" ); $GLOBALS['ID'] = mysql_insert_id(); if ($Status>=4) { do_pings(); update_lastmod(); } article_edit( get_status_message($Status).check_url_title($url_title) ); } else article_edit(); } //-------------------------------------------------------------- function article_save() { global $txp_user, $vars, $txpcfg, $prefs; extract($prefs); $incoming = psa($vars); $oldArticle = safe_row('Status, url_title, Title, unix_timestamp(LastMod) as sLastMod, LastModID','textpattern','ID = '.(int)$incoming['ID']); if (! ( ($oldArticle['Status'] >= 4 and has_privs('article.edit.published')) or ($oldArticle['Status'] >= 4 and $incoming['AuthorID']==$txp_user and has_privs('article.edit.own.published')) or ($oldArticle['Status'] < 4 and has_privs('article.edit')) or ($oldArticle['Status'] < 4 and $incoming['AuthorID']==$txp_user and has_privs('article.edit.own')))) { // Not allowed, you silly rabbit, you shouldn't even be here. // Show default editing screen. article_edit(); return; } if ($oldArticle['sLastMod'] != $incoming['sLastMod']) { article_edit(gTxt('concurrent_edit_by', array('{author}' => htmlspecialchars($oldArticle['LastModID']))), TRUE); return; } $incoming = textile_main_fields($incoming, $use_textile); extract(doSlash($incoming)); extract(array_map('assert_int', psa(array('ID', 'Status', 'textile_body', 'textile_excerpt')))); $Annotate = (int) $Annotate; if (!has_privs('article.publish') && $Status>=4) $Status = 3; if($reset_time) { $whenposted = "Posted=now()"; $when_ts = time(); } else { $when = $when_ts = strtotime($year.'-'.$month.'-'.$day.' '.$hour.':'.$minute.':'.$second)-tz_offset(); $whenposted = "Posted=from_unixtime($when)"; } if (empty($exp_year)) { $expires = 0; $whenexpires = "Expires=".NULLDATETIME; } else { 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; $expires = strtotime($exp_year.'-'.$exp_month.'-'.$exp_day.' '.$exp_hour.':'.$exp_minute.':'.$exp_second)-tz_offset(); $whenexpires = "Expires=from_unixtime($expires)"; } if ($expires) { if ($expires <= $when_ts) { article_edit(gTxt('article_expires_before_postdate')); return; } } //Auto-Update custom-titles according to Title, as long as unpublished and NOT customized if ( empty($url_title) || ( ($oldArticle['Status'] < 4) && ($oldArticle['url_title'] == $url_title ) && ($oldArticle['url_title'] == stripSpace($oldArticle['Title'],1)) && ($oldArticle['Title'] != $Title) ) ) { $url_title = stripSpace($Title_plain, 1); } $Keywords = doSlash(trim(preg_replace('/( ?[\r\n\t,])+ ?/s', ',', preg_replace('/ +/', ' ', ps('Keywords'))), ', ')); safe_update("textpattern", "Title = '$Title', Body = '$Body', Body_html = '$Body_html', Excerpt = '$Excerpt', Excerpt_html = '$Excerpt_html', Keywords = '$Keywords', Image = '$Image', Status = $Status, LastMod = now(), LastModID = '$txp_user', Section = '$Section', Category1 = '$Category1', Category2 = '$Category2', Annotate = $Annotate, textile_body = $textile_body, textile_excerpt = $textile_excerpt, override_form = '$override_form', url_title = '$url_title', AnnotateInvite = '$AnnotateInvite', custom_1 = '$custom_1', custom_2 = '$custom_2', custom_3 = '$custom_3', custom_4 = '$custom_4', custom_5 = '$custom_5', custom_6 = '$custom_6', custom_7 = '$custom_7', custom_8 = '$custom_8', custom_9 = '$custom_9', custom_10 = '$custom_10', $whenposted, $whenexpires", "ID = $ID" ); if($Status >= 4) { if ($oldArticle['Status'] < 4) { do_pings(); } update_lastmod(); } article_edit( get_status_message($Status).check_url_title($url_title) ); } //-------------------------------------------------------------- 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, unix_timestamp(Expires) as sExpires, unix_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.'
'; if (!empty($store_out)) { echo hInput('store', base64_encode(serialize($store_out))); } echo hInput('ID', $ID). eInput('article'). sInput($step). ''. startTable('edit'). ''.n. ''; if ($view == 'text') { //-- markup help -------------- echo side_help($textile_body, $textile_excerpt). '

'.gTxt('advanced_options').'

', '

'.gTxt('recent_articles').''.'

'. ''; } else { echo sp; } echo ''.n.''; //-- 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.'

'.sp.popHelp('title').br. ''; if ($step != 'create') { include_once txpath.'/publish/taghandlers.php'; $url = permlinkurl_id($ID); if ($Status != 4 and $Status != 5) { $url .= (strpos($url, '?') === FALSE ? '?' : '&') . 'txpreview='.intval($ID).'.'.time(); } echo sp.sp.''.gTxt('view').''; } echo '

'; } //-- 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(''.sp.popHelp('body').br. ''); } //-- excerpt -------------------- if ($articles_use_excerpts) { if ($view == 'text') { echo n.graf(''.sp.popHelp('excerpt').br. ''); } else { echo n.'
'; 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 '

'.gTxt('posted_by').': '.htmlspecialchars($AuthorID).' · '.safe_strftime('%d %b %Y · %X',$sPosted); if($sPosted != $sLastMod) { echo br.gTxt('modified_by').': '.htmlspecialchars($LastModID).' · '.safe_strftime('%d %b %Y · %X',$sLastMod); } echo '

'; } echo hInput('from_view',$view), ''; echo ''; //-- layer tabs ------------------- echo ($use_textile == USE_TEXTILE || $textile_body == USE_TEXTILE) ? '' : ' '; echo ''; echo ''; 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 '

', ($prev_id) ? prevnext_link('‹'.gTxt('prev'),'article','edit', $prev_id,gTxt('prev')) : '', ($next_id) ? prevnext_link(gTxt('next').'›','article','edit', $next_id,gTxt('next')) : '', '

'; } //-- status radios -------------- echo n.n.'
'. n.''.gTxt('status').''. n.status_radio($Status). n.'
'; //-- category selects ----------- echo n.n.'
'. n.''.gTxt('sort_display').''. n.graf(' '. '['.eLink('category', '', '', '', gTxt('edit')).']'.br. n.category_popup('Category1', $Category1, 'category-1')). n.graf(''.br. n.category_popup('Category2', $Category2, 'category-2')); //-- section select -------------- if(!$from_view && !$pull) $Section = getDefaultSection(); echo n.graf(' '. '['.eLink('section', '', '', '', gTxt('edit')).']'.br. section_popup($Section, 'section')). n.'
'. //-- "More" section n.n.'

'.gTxt('more').'

', ''; //-- 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.'
'. n.''.gTxt('timestamp').''. n.graf(checkbox('reset_time', '1', $reset_time, '', 'reset_time').''). 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.'
'; //-- 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.'
'. n.''.gTxt('expires').''. 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.'
'. // end "More" section n.n.''; //-- 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 '
'; } // ------------------------------------------------------------- function custField($num, $field, $content) { return n.n.graf(''.br. n.fInput('text', 'custom_'.$num, $content, 'edit', '', '', 22, '', 'custom-'.$num)); } // ------------------------------------------------------------- function checkIfNeighbour($whichway,$sPosted) { $sPosted = assert_int($sPosted); $dir = ($whichway == 'prev') ? '<' : '>'; $ord = ($whichway == 'prev') ? 'desc' : 'asc'; return safe_field("ID", "textpattern", "Posted $dir from_unixtime($sPosted) order by Posted $ord limit 1"); } //-------------------------------------------------------------- // remember to show markup help for both body and excerpt // if they are different function side_help($textile_body, $textile_excerpt) { if ($textile_body == USE_TEXTILE or $textile_excerpt == USE_TEXTILE) { return n.hed( ''.gTxt('textile_help').'' , 3, ' class="plain"'). n.''; } } //-------------------------------------------------------------- function status_radio($Status) { global $statuses; $Status = (!$Status) ? 4 : $Status; foreach ($statuses as $a => $b) { $out[] = n.t.'
  • '.radio('Status', $a, ($Status == $a) ? 1 : 0, 'status-'.$a). '
  • '; } return ''; } //-------------------------------------------------------------- function category_popup($name, $val, $id) { $rs = getTree('root', 'article'); if ($rs) { return treeSelectInput($name,$rs,$val, $id, 35); } return false; } //-------------------------------------------------------------- function section_popup($Section, $id) { $rs = safe_column('name', 'txp_section', "name != 'default'"); if ($rs) { return selectInput('Section', $rs, $Section, false, '', $id); } return false; } //-------------------------------------------------------------- function tab($tabevent,$view) { $state = ($view==$tabevent) ? 'up' : 'down'; $out = "
  • "; $out.=($tabevent!=$view) ? ''.gTxt($tabevent).'' : gTxt($tabevent); $out.='
  • '; return $out; } //-------------------------------------------------------------- function getDefaultSection() { return safe_field("name", "txp_section","is_default=1"); } // ------------------------------------------------------------- function form_pop($form, $id) { $arr = array(' '); $rs = safe_column('name', 'txp_form', "type = 'article' and name != 'default' order by name"); if ($rs) { return selectInput('override_form', $rs, $form, true, '', $id); } } // ------------------------------------------------------------- function check_url_title($url_title) { // Check for blank or previously used identical url-titles if (strlen($url_title) === 0) { return gTxt('url_title_is_blank'); } else { $url_title_count = safe_count('textpattern', "url_title = '$url_title'"); if ($url_title_count > 1) { return gTxt('url_title_is_multiple', array('{count}' => $url_title_count)); } } return ''; } // ------------------------------------------------------------- function get_status_message($Status) { switch ($Status){ case 3: return gTxt("article_saved_pending"); case 2: return gTxt("article_saved_hidden"); case 1: return gTxt("article_saved_draft"); default: return gTxt('article_posted'); } } // ------------------------------------------------------------- function textile_main_fields($incoming, $use_textile) { global $txpcfg; include_once txpath.'/lib/classTextile.php'; $textile = new Textile(); $incoming['Title_plain'] = $incoming['Title']; $incoming['url_title'] = preg_replace('|[\x00-\x1f#%+/?\x7f]|', '', $incoming['url_title']); if ($incoming['textile_body'] == LEAVE_TEXT_UNTOUCHED) { $incoming['Body_html'] = trim($incoming['Body']); }elseif ($incoming['textile_body'] == USE_TEXTILE){ $incoming['Body_html'] = $textile->TextileThis($incoming['Body']); $incoming['Title'] = $textile->TextileThis($incoming['Title'],'',1); }elseif ($incoming['textile_body'] == CONVERT_LINEBREAKS){ $incoming['Body_html'] = nl2br(trim($incoming['Body'])); } if ($incoming['textile_excerpt'] == LEAVE_TEXT_UNTOUCHED) { $incoming['Excerpt_html'] = trim($incoming['Excerpt']); }elseif ($incoming['textile_excerpt'] == USE_TEXTILE){ $incoming['Excerpt_html'] = $textile->TextileThis($incoming['Excerpt']); }elseif ($incoming['textile_excerpt'] == CONVERT_LINEBREAKS){ $incoming['Excerpt_html'] = nl2br(trim($incoming['Excerpt'])); } return $incoming; } // ------------------------------------------------------------- function do_pings() { global $txpcfg, $prefs, $production_status; # only ping for Live sites if ($production_status !== 'live') return; include_once txpath.'/lib/IXRClass.php'; callback_event('ping'); if ($prefs['ping_textpattern_com']) { $tx_client = new IXR_Client('http://textpattern.com/xmlrpc/'); $tx_client->query('ping.Textpattern', $prefs['sitename'], hu); } if ($prefs['ping_weblogsdotcom']==1) { $wl_client = new IXR_Client('http://rpc.pingomatic.com/'); $wl_client->query('weblogUpdates.ping', $prefs['sitename'], hu); } } ?>