wiki
[ class tree: wiki ] [ index: wiki ] [ all elements ]

Source for file edit.php

Documentation is available at edit.php

  1. <?php
  2. /**
  3.  * $Header: /cvsroot/bitweaver/_bit_wiki/edit.php,v 1.30 2007/01/21 20:19:45 jht001 Exp $
  4.  *
  5.  * Copyright( c ) 2004 bitweaver.org
  6.  * Copyright( c ) 2003 tikwiki.org
  7.  * Copyright( c ) 2002-2003, Luis Argerich, Garland Foster, Eduardo Polidor, et. al.
  8.  * All Rights Reserved. See copyright.txt for details and a complete list of authors.
  9.  * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details
  10.  *
  11.  * $Id: edit.php,v 1.30 2007/01/21 20:19:45 jht001 Exp $
  12.  * @package wiki
  13.  * @subpackage functions
  14.  */
  15.  
  16. /**
  17.  * required setup
  18.  */
  19. require_once'../bit_setup_inc.php' );
  20.  
  21. include_onceWIKI_PKG_PATH.'BitBook.php' );
  22. include_onceLIBERTY_PKG_PATH.'edit_help_inc.php' );
  23.  
  24. $gBitSystem->verifyPackage'wiki' );
  25.  
  26. includeWIKI_PKG_PATH.'lookup_page_inc.php' );
  27.  
  28. // Get plugins with descriptions
  29. global $wikilib$gLibertySystem;
  30.  
  31. #edit preview needs this
  32. if!isset$_REQUEST['title'&& isset$gContent->mInfo['title') ) {
  33.     $_REQUEST['title'$gContent->mInfo['title'];
  34. }
  35.  
  36. $wiki_sandbox FALSE;
  37. if( ( !empty$_REQUEST['page'&& $_REQUEST['page'== 'SandBox' || !empty$_REQUEST['title'&& $_REQUEST['title'== 'SandBox' ) ) {
  38.     $gContent->mInfo['title''SandBox';
  39.     $wiki_sandbox TRUE;
  40. }
  41.  
  42.  
  43. if$wiki_sandbox && !$gBitSystem->isFeatureActive'wiki_sandbox' ) ) {
  44.     $gBitSystem->fatalError"The SandBox is disabled" );
  45. elseif!$wiki_sandbox && !$gContent->hasUserPermission'p_wiki_edit_page' ) ) {
  46.     $gBitSystem->fatalError'Permission denied you cannot edit the page named "'.$gContent->getTitle().'"' );
  47. }
  48.  
  49. if$gContent->isLocked() ) {
  50.     $gBitSystem->fatalError'Cannot edit page because it is locked' );
  51. }
  52.  
  53. // see if we should show the attachments tab at all
  54. foreach$gLibertySystem->mPlugins as $plugin {
  55.     if( ( $plugin['plugin_type'== 'storage' && $plugin['is_active'== 'y' ) ) {
  56.         $gBitSmarty->assign'show_attachments','y' );
  57.     }
  58. }
  59.  
  60. function  extract_section($data,$section{
  61.     global $gContent$gBitSystem;
  62.     if$gContent->mInfo['format_guid'== PLUGIN_GUID_TIKIWIKI {
  63.         $section_data preg_split"/\n(".str_repeat"!"$gBitSystem->getConfig"wiki_section_edit" ) ) )."[^!])/""\n$data"-1PREG_SPLIT_DELIM_CAPTURE );
  64.         $a ($section 12;
  65.         $b $a 1;
  66.         return $section_data[$a$section_data[$b];
  67.     }
  68. }
  69.  
  70. function  replace_section($data,$section,$new_section_data{
  71.     global $gContent$gBitSystem;
  72.     if$gContent->mInfo['format_guid'== PLUGIN_GUID_TIKIWIKI {
  73.         $section_data preg_split("/(\n".str_repeat"!"$gBitSystem->getConfig"wiki_section_edit" ) ) )."[^!])/""\n$data,-1,PREG_SPLIT_DELIM_CAPTURE);
  74.         $a ($section 12;
  75.         $b $a 1;
  76.         $section_data[$a"\n";
  77.         $section_data[$b$new_section_data;
  78.         return substr(implode('',$section_data),1);
  79.     }
  80. }
  81.  
  82. function compare_import_versions$a1$a2 {
  83.     return $a1["version"$a2["version"];
  84. }
  85.  
  86. /**
  87.  * \brief Parsed HTML tree walker( used by HTML sucker )
  88.  *
  89.  * This is initial implementation( stupid... w/o any intellegence( almost : ) )
  90.  * It is rapidly designed version... just for test: 'can this feature be useful'.
  91.  * Later it should be replaced by well designed one :) don't bash me now : )
  92.  *
  93.  * \param &$c array -- parsed HTML
  94.  * \param &$src string -- output string
  95.  * \param &$p array -- ['stack'] = closing strings stack,
  96.                        ['listack'] = stack of list types currently opened
  97.                        ['first_td'] = flag: 'is <tr> was just before this <td>'
  98.  */
  99. function walk_and_parse&$c&$src&$p {
  100.     for$i=0$i <= $c["contentpos"]$i++ {
  101.         // If content type 'text' output it to destination...
  102.         if$c[$i]["type"== "text" {
  103.             $src .= $c[$i]["data"];
  104.         elseif$c[$i]["type"== "tag" {
  105.             if$c[$i]["data"]["type"== "open" {
  106.                 // Open tag type
  107.                 switch$c[$i]["data"]["name"{
  108.                     case "br"$src .= "\n"break;
  109.                     case "title"$src .= "\n!"$p['stack'][array'tag' => 'title''string' => "\n" )break;
  110.                     case "p"$src .= "\n"$p['stack'][array'tag' => 'p''string' => "\n" )break;
  111.                     case "b"$src .= '__'$p['stack'][array'tag' => 'b''string' => '__' )break;
  112.                     case "i"$src .= "''"$p['stack'][array'tag' => 'i''string' => "''" )break;
  113.                     case "u"$src .= "=="$p['stack'][array'tag' => 'u''string' => "==" )break;
  114.                     case "center"$src .= '::'$p['stack'][array'tag' => 'center''string' => '::' )break;
  115.                     case "code"$src .= '-+';  $p['stack'][array'tag' => 'code''string' => '+-' )break;
  116.                     // headers detection looks like real suxx code...
  117.                     // but possible it run faster :) I don't know where is profiler in PHP...
  118.                     case "h1"$src .= "\n!"$p['stack'][array'tag' => 'h1''string' => "\n" )break;
  119.                     case "h2"$src .= "\n!!"$p['stack'][array'tag' => 'h2''string' => "\n" )break;
  120.                     case "h3"$src .= "\n!!!"$p['stack'][array'tag' => 'h3''string' => "\n" )break;
  121.                     case "h4"$src .= "\n!!!!"$p['stack'][array'tag' => 'h4''string' => "\n" )break;
  122.                     case "h5"$src .= "\n!!!!!"$p['stack'][array'tag' => 'h5''string' => "\n" )break;
  123.                     case "h6"$src .= "\n!!!!!!"$p['stack'][array'tag' => 'h6''string' => "\n" )break;
  124.                     case "pre"$src .= '~pp~'$p['stack'][array'tag' => 'pre''string' => '~/pp~' )break;
  125.                     // Table parser
  126.                     case "table"$src .= '||'$p['stack'][array'tag' => 'table''string' => '||' )break;
  127.                     case "tr"$p['first_td'truebreak;
  128.                     case "td"$src .= $p['first_td''' '|'$p['first_td'falsebreak;
  129.                     // Lists parser
  130.                     case "ul"$p['listack']['*'break;
  131.                     case "ol"$p['listack']['#'break;
  132.                     case "li":
  133.                         // Generate wiki list item according to current list depth.
  134.                         //( ensure '*/#' starts from begining of line )
  135.                         for$l ''strlen$l count$p['listack')$l .= end$p['listack') );
  136.                         $src .= "\n$l ";
  137.                         break;
  138.                     case "font":
  139.                         // If color attribute present in <font> tag
  140.                         ifisset$c[$i]["pars"]["color"]["value") ) {
  141.                             $src .= '~~'.$c[$i]["pars"]["color"]["value"].':';
  142.                             $p['stack'][array'tag' => 'font''string' => '~~' );
  143.                         }
  144.                         break;
  145.                     case "img":
  146.                         // If src attribute present in <img> tag
  147.                         ifisset$c[$i]["pars"]["src"]["value") ) {
  148.                             // Note what it produce( img ) not {img}! Will fix this below...
  149.                             $src .= '( img src='.$c[$i]["pars"]["src"]["value"].' )';
  150.                         }
  151.                         break;
  152.                     case "a":
  153.                         // If href attribute present in <a> tag
  154.                         ifisset$c[$i]["pars"]["href"]["value") ) {
  155.                             $src .= '['.$c[$i]["pars"]["href"]["value"].'|';
  156.                             $p['stack'][array'tag' => 'a''string' => ']' );
  157.                         }
  158.                         break;
  159.                 }
  160.             else {
  161.                 // This is close tag type. Is that smth we r waiting for?
  162.                 switch$c[$i]["data"]["name"{
  163.                 case "ul":
  164.                     ifend$p['listack'== '*' array_pop$p['listack');
  165.                     break;
  166.                 case "ol":
  167.                     ifend$p['listack'== '#' array_pop$p['listack');
  168.                     break;
  169.                 default:
  170.                     $e end$p['stack');
  171.                     if$c[$i]["data"]["name"== $e['tag'{
  172.                         $src .= $e['string'];
  173.                         array_pop$p['stack');
  174.                     }
  175.                     break;
  176.                 }
  177.             }
  178.         }
  179.         // Recursive call on tags with content...
  180.         ifisset$c[$i]["content") ) {
  181. //            if( substr( $src, -1 )!= " " )$src .= " ";
  182.             walk_and_parse$c[$i]["content"]$src$p );
  183.         }
  184.     }
  185. }
  186. ifisset$_REQUEST["suck_url") ) {
  187.     // Suck another page and append to the end of current
  188.     require_onceUTIL_PKG_PATH.'htmlparser/html_parser_inc.php' );
  189.     $suck_url = isset$_REQUEST["suck_url"$_REQUEST["suck_url"'';
  190.     $parsehtml = isset$_REQUEST["parsehtml"$_REQUEST["parsehtml"== 'on' 'y' 'n' )'n';
  191.     ifisset$_REQUEST['do_suck'&& strlen$suck_url {
  192.         // \note by zaufi
  193. //   This is ugly implementation of wiki HTML import.
  194.         //   I think it should be plugable import/export converters with ability
  195.         //   to choose from edit form what converter to use for operation.
  196.         //   In case of import converter, it can try to guess what source
  197.         //   file is( using mime type from remote server response ).
  198.         //   Of couse converters may have itsown configuration panel what should be
  199.         //   pluged into wiki page edit form too...( like HTML importer may have
  200.         //   flags 'strip HTML tags' and 'try to convert HTML to wiki' : )
  201.         //   At least one export filter for wiki already coded : ) -- PDF exporter...
  202.         
  203.         $sdta @file_get_contents$suck_url );
  204.         ifisset$php_errormsg && strlen$php_errormsg ) ) {
  205.             $gBitSystem->fatalError'Can\'t import remote HTML page' );
  206.         }
  207.         // Need to parse HTML?
  208.                 if$parsehtml == 'y' {
  209.             // Read compiled( serialized ) grammar
  210.             $grammarfile UTIL_PKG_PATH.'htmlparser/htmlgrammar.cmp';
  211.             if!$fp @fopen$grammarfile,'r' ) ) {
  212.                 $gBitSystem->fatalError'Can\'t parse remote HTML page' );
  213.             }
  214.             $grammar unserializefread$fpfilesize$grammarfile ) ) );
  215.             fclose$fp );
  216.             // create parser object, insert html code and parse it
  217.             $htmlparser new HtmlParser$sdta$grammar'');
  218.             $htmlparser->Parse();
  219.             // Should I try to convert HTML to wiki?
  220.                         $parseddata '';
  221.             $p =  array'stack' => array()'listack' => array()'first_td' => false );
  222.             walk_and_parse$htmlparser->content$parseddata$p );
  223.             // Is some tags still opened?( It can be if HTML not valid, but this is not reason
  224. // to produce invalid wiki : )
  225.             
  226.             whilecount$p['stack') ) {
  227.                 $e end$p['stack');
  228.                 $sdta .= $e['string'];
  229.                 array_pop$p['stack');
  230.             }
  231.             // Unclosed lists r ignored... wiki have no special start/end lists syntax....
  232. // OK. Things remains to do:
  233.             // 1 ) fix linked images
  234.             
  235.             $parseddata preg_replace',\[(.*)\|\( img src=(.*)\)\],mU','{img src=$2 link=$1}'$parseddata );
  236.             // 2 ) fix remains images( not in links )
  237.             $parseddata preg_replace',\( img src=(.*)\),mU','{img src=$1}'$parseddata );
  238.             // 3 ) remove empty lines
  239.             $parseddata preg_replace",[\n]+,mU","\n"$parseddata );
  240.             // Reassign previous data
  241.             $sdta $parseddata;
  242.         }
  243.         $_REQUEST['edit'.= $sdta;
  244.     }
  245. }
  246. //
  247.  
  248. //include_once( WIKI_PKG_PATH.'page_setup_inc.php' );
  249. // Now check permissions to access this page
  250.  
  251.  
  252.  
  253. ifisset$gContent->mInfo['wiki_cache'&& $gContent->mInfo['wiki_cache']!={
  254.     $wiki_cache $gContent->mInfo['wiki_cache'];
  255.     $gBitSmarty->assign'wiki_cache',$wiki_cache );
  256. }
  257.  
  258. if!empty$gContent->mInfo ) ) {
  259.     $formInfo $gContent->mInfo;
  260.     $data_to_edit !empty$gContent->mInfo['data'$gContent->mInfo['data''';
  261.     if (!empty($_REQUEST['section'])) {
  262.         $section $_REQUEST['section'];
  263.         $data_to_edit extract_section($data_to_edit,$section);
  264.         $formInfo['data'$data_to_edit;
  265.         $formInfo['edit_section'1;
  266.         $formInfo['section'$_REQUEST['section'];
  267.     }
  268.  
  269.     $formInfo['edit'$data_to_edit;
  270.     $formInfo['edit_comment''';
  271. }
  272.  
  273. $gBitSmarty->assign'footnote''' );
  274. $gBitSmarty->assign'has_footnote''n' );
  275. if$gBitSystem->isFeatureActive'wiki_footnotes' ) ) {
  276.     if$gBitUser->mUserId {
  277.         $footnote $gContent->getFootnote$gBitUser->mUserId );
  278.         $gBitSmarty->assign'footnote'$footnote );
  279.         if$footnote )
  280.             $gBitSmarty->assign'has_footnote''y' );
  281.         $gBitSmarty->assign'parsed_footnote'$wikilib->parseData$footnote ) );
  282.         ifisset$_REQUEST['footnote') ) {
  283.  
  284.             $gBitSmarty->assign'parsed_footnote'$wikilib->parseData$_REQUEST['footnote') );
  285.             $gBitSmarty->assign'footnote'$_REQUEST['footnote');
  286.             $gBitSmarty->assign'has_footnote''y' );
  287.             ifempty$_REQUEST['footnote') ) {
  288.                 $gContent->expungeFootnote$gBitUser->mUserId );
  289.             else {
  290.                 $gContent->storeFootnote$gBitUser->mUserId$_REQUEST['footnote');
  291.             }
  292.         }
  293.     }
  294. }
  295. ifisset$_REQUEST["template_id"&& $_REQUEST["template_id"{
  296.     $template_data $wikilib->get_template$_REQUEST["template_id");
  297.     $_REQUEST["edit"$template_data["content"];
  298.     $_REQUEST["preview"1;
  299. }
  300.  
  301. ifisset$_REQUEST["edit") ) {
  302.     $formInfo['edit'$_REQUEST["edit"];
  303. }
  304. if(isset($_REQUEST["section"])) {
  305.     $formInfo['section'$_REQUEST["section"];
  306.     $formInfo['edit_section'1;
  307. }
  308. ifisset$_REQUEST['title') ) {
  309.     $formInfo['title'$_REQUEST['title'];
  310. }
  311. ifisset$_REQUEST["description") ) {
  312.     $formInfo['description'$_REQUEST["description"];
  313. }
  314. ifisset$_REQUEST["edit_comment") ) {
  315.     $formInfo['edit_comment'$_REQUEST["edit_comment"];
  316. else {
  317.     $formInfo['edit_comment''';
  318. }
  319.  
  320. $cat_obj_type BITPAGE_CONTENT_TYPE_GUID;
  321.  
  322. if$gBitSystem->isFeatureActive'wiki_copyrights' ) ) {
  323.     ifisset$_REQUEST['copyrightTitle') ) {
  324.         $gBitSmarty->assign'copyrightTitle'$_REQUEST["copyrightTitle");
  325.     }
  326.     ifisset$_REQUEST['copyrightYear') ) {
  327.         $gBitSmarty->assign'copyrightYear'$_REQUEST["copyrightYear");
  328.     }
  329.     ifisset$_REQUEST['copyrightAuthors') ) {
  330.         $gBitSmarty->assign'copyrightAuthors'$_REQUEST["copyrightAuthors");
  331.     }
  332. }
  333.  
  334.  
  335. function htmldecode$string {
  336.    $string strtr$stringarray_flipget_html_translation_tableHTML_ENTITIES ) ) );
  337.    $string preg_replace"/&#([0-9]+);/me""chr('\\1')"$string );
  338.    return $string;
  339. }
  340. function parse_output&$obj&$parts,$i {
  341.     if!empty$obj->parts ) ) {
  342.         for$i=0$i<count$obj->parts )$i++ {
  343.             parse_output$obj->parts[$i]$parts,$i );
  344.         }
  345.     else {
  346.         $ctype $obj->ctype_primary.'/'.$obj->ctype_secondary;
  347.         switch$ctype {
  348.             case 'application/x-tikiwiki':
  349.                 $aux["body"$obj->body;
  350.                 $ccc=$obj->headers["content-type"];
  351.                 $items split';',$ccc );
  352.                 foreach$items as $item {
  353.                     $portions split'=',$item );
  354.                     ifisset$portions[0&&isset$portions[1) ) {
  355.                         $aux[trim$portions[0)]=trim$portions[1);
  356.                     }
  357.                 }
  358.                 $parts[]=$aux