WikiPage.class.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. <?php
  2. /**
  3. * Define a page.
  4. * @author Valentin CARRUESCO
  5. * @category Plugin
  6. * @license copyright
  7. */
  8. class WikiPage extends Entity{
  9. public $id,$label,$content,$state,$path,$category,$slug,$sort = 0;
  10. const PUBLISHED = 'published';
  11. const DRAFT = 'draft';
  12. protected $TABLE_NAME = 'wiki_page';
  13. public $links = array(
  14. 'category' => 'WikiCategory'
  15. );
  16. public $fields =
  17. array(
  18. 'id' => 'key',
  19. 'label' => 'string',
  20. 'state' => 'string',
  21. 'category' => 'int',
  22. 'slug' => 'string',
  23. 'sort' => 'int',
  24. 'path' => 'string'
  25. );
  26. public static function defaultContent(){
  27. $default = 'Mon contenu ici...';
  28. $defaultFile = File::dir().'wiki'.SLASH.'default.md';
  29. if(file_exists($defaultFile)) $default = file_get_contents($defaultFile);
  30. return $default;
  31. }
  32. public static function workspace(){
  33. return File::dir().'wiki'.SLASH.'pages';
  34. }
  35. public static function uploads(){
  36. return File::dir().'wiki'.SLASH.'uploads';
  37. }
  38. public static function path_from_label($label){
  39. return preg_replace('|[\?\\\/\*\:\|\<\>]|i', '-',$label);
  40. }
  41. public function author(){
  42. return User::byLogin($this->creator, false)->fullName();
  43. }
  44. public function created(){
  45. return relative_time($this->created);
  46. }
  47. public function updater(){
  48. return User::byLogin($this->updater, false)->fullName();
  49. }
  50. public function updated(){
  51. return relative_time($this->updated);
  52. }
  53. public function html(){
  54. $markdown = new WikiPageParsedown();
  55. return $markdown->text($this->content);
  56. }
  57. public function content(){
  58. $this->content = file_get_contents(self::workspace().SLASH.wiki_os_encode($this->path));
  59. }
  60. }
  61. require_once(__DIR__.SLASH.'lib'.SLASH.'Parsedown.php');
  62. //Etend la classe parsedown pour y ajouter des features (ex:le souligné (__texte souligné__))
  63. class WikiPageParsedown extends Parsedown{
  64. protected function blockCode($Line, $Block = null)
  65. {
  66. if (isset($Block) and $Block['type'] === 'Paragraph' and ! isset($Block['interrupted']))
  67. {
  68. return;
  69. }
  70. if ($Line['indent'] >= 4)
  71. {
  72. $text = substr($Line['body'], 4);
  73. $Block = array(
  74. 'element' => array(
  75. 'name' => 'pre',
  76. 'element' => array(
  77. 'name' => 'code',
  78. 'attributes' => array('class' => "block-code"),
  79. 'text' => $text,
  80. ),
  81. ),
  82. );
  83. return $Block;
  84. }
  85. }
  86. protected function blockQuote($Line)
  87. {
  88. if (preg_match('/^>[ ]?+(.*+)/', $Line['text'], $matches))
  89. {
  90. $Block = array(
  91. 'element' => array(
  92. 'name' => 'blockquote',
  93. 'attributes' => array('class' => "blockquote"),
  94. 'handler' => array(
  95. 'function' => 'linesElements',
  96. 'argument' => (array) $matches[1],
  97. 'destination' => 'elements',
  98. )
  99. ),
  100. );
  101. return $Block;
  102. }
  103. }
  104. protected function blockTable($Line, array $Block = null)
  105. {
  106. if ( ! isset($Block) or $Block['type'] !== 'Paragraph' or isset($Block['interrupted']))
  107. {
  108. return;
  109. }
  110. if (
  111. strpos($Block['element']['handler']['argument'], '|') === false
  112. and strpos($Line['text'], '|') === false
  113. and strpos($Line['text'], ':') === false
  114. or strpos($Block['element']['handler']['argument'], "\n") !== false
  115. ) {
  116. return;
  117. }
  118. if (chop($Line['text'], ' -:|') !== '')
  119. {
  120. return;
  121. }
  122. $alignments = array();
  123. $divider = $Line['text'];
  124. $divider = trim($divider);
  125. $divider = trim($divider, '|');
  126. $dividerCells = explode('|', $divider);
  127. foreach ($dividerCells as $dividerCell)
  128. {
  129. $dividerCell = trim($dividerCell);
  130. if ($dividerCell === '')
  131. {
  132. return;
  133. }
  134. $alignment = null;
  135. if ($dividerCell[0] === ':')
  136. {
  137. $alignment = 'left';
  138. }
  139. if (substr($dividerCell, - 1) === ':')
  140. {
  141. $alignment = $alignment === 'left' ? 'center' : 'right';
  142. }
  143. $alignments []= $alignment;
  144. }
  145. # ~
  146. $HeaderElements = array();
  147. $header = $Block['element']['handler']['argument'];
  148. $header = trim($header);
  149. $header = trim($header, '|');
  150. $headerCells = explode('|', $header);
  151. if (count($headerCells) !== count($alignments))
  152. {
  153. return;
  154. }
  155. foreach ($headerCells as $index => $headerCell)
  156. {
  157. $headerCell = trim($headerCell);
  158. $HeaderElement = array(
  159. 'name' => 'th',
  160. 'handler' => array(
  161. 'function' => 'lineElements',
  162. 'argument' => $headerCell,
  163. 'destination' => 'elements',
  164. )
  165. );
  166. if (isset($alignments[$index]))
  167. {
  168. $alignment = $alignments[$index];
  169. $HeaderElement['attributes'] = array(
  170. 'style' => "text-align: $alignment;"
  171. );
  172. }
  173. $HeaderElements []= $HeaderElement;
  174. }
  175. # ~
  176. $Block = array(
  177. 'alignments' => $alignments,
  178. 'identified' => true,
  179. 'element' => array(
  180. 'name' => 'table',
  181. 'attributes' => array('class' => "table"), /* + sys1 */
  182. 'elements' => array(),
  183. ),
  184. );
  185. $Block['element']['elements'] []= array(
  186. 'name' => 'thead',
  187. );
  188. $Block['element']['elements'] []= array(
  189. 'name' => 'tbody',
  190. 'elements' => array(),
  191. );
  192. $Block['element']['elements'][0]['elements'] []= array(
  193. 'name' => 'tr',
  194. 'elements' => $HeaderElements,
  195. );
  196. return $Block;
  197. }
  198. protected function blockFencedCode($Line)
  199. {
  200. $marker = $Line['text'][0];
  201. $openerLength = strspn($Line['text'], $marker);
  202. if ($openerLength < 3)
  203. {
  204. return;
  205. }
  206. $infostring = trim(substr($Line['text'], $openerLength), "\t ");
  207. if (strpos($infostring, '`') !== false)
  208. {
  209. return;
  210. }
  211. $Element = array(
  212. 'name' => 'code',
  213. 'attributes' => array('class' => "block-code"),
  214. 'text' => '',
  215. );
  216. if ($infostring !== '')
  217. {
  218. $Element['attributes'] = array('class' => "language-$infostring");
  219. }
  220. $Block = array(
  221. 'char' => $marker,
  222. 'openerLength' => $openerLength,
  223. 'element' => array(
  224. 'name' => 'pre',
  225. 'element' => $Element,
  226. ),
  227. );
  228. return $Block;
  229. }
  230. protected function inlineCode($Excerpt)
  231. {
  232. $marker = $Excerpt['text'][0];
  233. if (preg_match('/^(['.$marker.']++)[ ]*+(.+?)[ ]*+(?<!['.$marker.'])\1(?!'.$marker.')/s', $Excerpt['text'], $matches))
  234. {
  235. $text = $matches[2];
  236. $text = preg_replace('/[ ]*+\n/', ' ', $text);
  237. return array(
  238. 'extent' => strlen($matches[0]),
  239. 'element' => array(
  240. 'name' => 'code',
  241. 'attributes' => array('class' => "inline-code"),
  242. 'text' => $text,
  243. ),
  244. );
  245. }
  246. }
  247. protected function inlineEmphasis($Excerpt)
  248. {
  249. if ( ! isset($Excerpt['text'][1]))
  250. {
  251. return;
  252. }
  253. $marker = $Excerpt['text'][0];
  254. if(preg_match('/^__([^__]*)__/us', $Excerpt['text'], $matches)){
  255. $emphasis = 'u';
  256. }else if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches))
  257. {
  258. $emphasis = 'strong';
  259. }
  260. elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches))
  261. {
  262. $emphasis = 'em';
  263. }
  264. else
  265. {
  266. return;
  267. }
  268. return array(
  269. 'extent' => strlen($matches[0]),
  270. 'element' => array(
  271. 'name' => $emphasis,
  272. 'attributes' => array(
  273. 'class' => 'emphasis-underscore' ,
  274. ),
  275. 'handler' => array(
  276. 'function' => 'lineElements',
  277. 'argument' => $matches[1],
  278. 'destination' => 'elements',
  279. )
  280. ),
  281. );
  282. }
  283. }
  284. ?>