PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/application/protected/extensions/widgets/ddeditor/DDEditor.php

https://bitbucket.org/dinhtrung/yiicorecms/
PHP | 243 lines | 125 code | 6 blank | 112 comment | 28 complexity | acb2adfef171b4af88ea77a98061cfa0 MD5 | raw file
Possible License(s): GPL-3.0, BSD-3-Clause, CC0-1.0, BSD-2-Clause, GPL-2.0, LGPL-2.1, LGPL-3.0
  1. <?php
  2. /**
  3. * DDEditor Class File
  4. *
  5. * @author Joachim Werner <joachim.werner@diggin-data.de>
  6. * @link http://www.diggin-data.de
  7. */
  8. /**
  9. * DDEditor creates a textarea editor for Markdown syntax
  10. * The editor has some buttons to replace selected text in a textarea
  11. * with common Mardown syntax
  12. *
  13. * @author Joachim Werner <joachim.werner@diggin-data.de>
  14. * @version 0.4
  15. */
  16. class DDEditor extends CWidget
  17. {
  18. // {{{ Members
  19. /**
  20. * model - The model upon which the activeTextarea control is based on
  21. *
  22. * @var mixed
  23. * @access public
  24. */
  25. public $model;
  26. /**
  27. * The attribute name for which the activeTextarea control shall be created
  28. * @var mixed
  29. * @access public
  30. */
  31. public $attribute;
  32. /**
  33. * Array of additional HTML options for the textarea control
  34. *
  35. * @var array
  36. * @access public
  37. */
  38. public $htmlOptions=array();
  39. public $snippets = array('bold', 'italic', 'h', 'link', 'img', 'li', 'hr', 'table', 'code', 'code2', 'addlines', 'remlines', 'preview');
  40. public $additionalSnippets = array();
  41. /**
  42. * Request which returns via AJAX the rendered preview for the Markdown text
  43. *
  44. * @var mixed
  45. * @access public
  46. */
  47. public $previewRequest;
  48. /**
  49. * The ID of the activeTextarea
  50. *
  51. * @var mixed
  52. * @access private
  53. */
  54. private $editorId;
  55. // }}}
  56. // {{{ run
  57. /**
  58. * Runs the widget
  59. *
  60. * @access public
  61. * @return void
  62. */
  63. public function run()
  64. {
  65. $this->registerClientScripts();
  66. echo $this->createMarkup();
  67. } // }}}
  68. // {{{ createMarkup
  69. /**
  70. * Creates the widget's markup
  71. *
  72. * @access public
  73. * @return void
  74. */
  75. public function createMarkup()
  76. {
  77. if(!isset($this->htmlOptions['rows'])) {
  78. $attribute = $this->attribute;
  79. $text = $this->model->$attribute;
  80. if (strpos($text, "\n") === FALSE) {
  81. //MAC?!
  82. $text = str_replace( "\r", "\n", $text );
  83. } else {
  84. //Windows has \r\n
  85. $text = str_replace( "\r", '', $text );
  86. }
  87. $this->htmlOptions['rows'] = count(explode("\n", $text));
  88. }
  89. $this->render(
  90. 'editor',
  91. array(
  92. 'model'=>$this->model,
  93. 'attribute'=>$this->attribute,
  94. 'htmlOptions'=>$this->htmlOptions,
  95. 'editorId' => $this->editorId,
  96. 'snippets' => $this->snippets,
  97. 'additionalSnippets'=>$this->additionalSnippets,
  98. )
  99. );
  100. } // }}}
  101. // {{{ registerClientScripts
  102. /**
  103. * Registers the clientside widget files (css & js)
  104. */
  105. private function registerClientScripts() {
  106. // Get the resources path
  107. $resources = dirname(__FILE__).'/resources';
  108. $cs = Yii::app()->clientScript;
  109. // publish the files
  110. $baseUrl = Yii::app()->assetManager->publish($resources);
  111. // register the files
  112. // Stylesheet
  113. if(is_file($resources.'/styles.css')) {
  114. $cs->registerCssFile($baseUrl.'/styles.css');
  115. }
  116. if(is_file($resources.'/editor.js')) {
  117. $cs->registerScriptFile($baseUrl.'/editor.js');
  118. }
  119. self::resolveNameID($this->model,$this->attribute,$this->htmlOptions);
  120. $this->editorId = $this->htmlOptions['id'];
  121. $c=1;
  122. // Create preview request URL
  123. $url = Yii::app()->urlManager->createUrl($this->previewRequest,array('attribute'=>$this->attribute));
  124. $scriptId = uniqid('ed_').'_';
  125. // Bold
  126. if (in_array('bold', $this->snippets))
  127. $cs->registerScript($scriptId.$c++,"jQuery('#".$this->editorId."-editor-bold').click(function(){insertTags('".$this->editorId."','**','**','bold ')});");
  128. // Italic
  129. if (in_array('italic', $this->snippets))
  130. $cs->registerScript($scriptId.$c++,"jQuery('#".$this->editorId."-editor-italic').click(function(){insertTags('".$this->editorId."','_','_','italic ')});");
  131. // Headings
  132. if (in_array('h', $this->snippets))
  133. $cs->registerScript($scriptId.$c++,"jQuery('#".$this->editorId."-editor-h').change(function(){insertTags('".$this->editorId."',padText('#',this.value)+' ',' '+padText('#',this.value),'Heading '+this.value)});");
  134. // Link
  135. if (in_array('link', $this->snippets))
  136. $cs->registerScript($scriptId.$c++,"jQuery('#".$this->editorId."-editor-link').click(function(){insertTags('".$this->editorId."','[','](http://...)','Link Description')});");
  137. // Image
  138. // $cs->registerScript($scriptId.$c++,"jQuery('#".$this->editorId."-editor-img').click(function(){insertTags('".$this->editorId."','![Alt Text](',' \"Title\")','Image URL')});");
  139. // Image 2
  140. if (in_array('img', $this->snippets))
  141. $cs->registerScript($scriptId.$c++,"jQuery('#".$this->editorId."-editor-img2').change(function(){insertTags('".$this->editorId."',this.value+'[Heading/Alt Text](',' \"Title\")','path/to/image.jpg')});");
  142. // List Item
  143. if (in_array('li', $this->snippets))
  144. $cs->registerScript($scriptId.$c++,"jQuery('#".$this->editorId."-editor-li').click(function(){insertTags('".$this->editorId."','* ','','List Item ')});");
  145. // HR
  146. if (in_array('hr', $this->snippets))
  147. $cs->registerScript($scriptId.$c++,"jQuery('#".$this->editorId."-editor-hr').click(function(){insertTags('".$this->editorId."','****bslashN','','')});");
  148. // Table
  149. if (in_array('table', $this->snippets))
  150. $cs->registerScript($scriptId.$c++,"jQuery('#".$this->editorId."-editor-table').click(function(){insertTags('".$this->editorId."','| Header | Header |bslashN| ------ | ------ | bslashN| ',' | Cell |bslashN','Cell')});");
  151. // Code
  152. if (in_array('code', $this->snippets))
  153. $cs->registerScript($scriptId.$c++,"jQuery('#".$this->editorId."-editor-code').click(function(){insertTags('".$this->editorId."','`','`','sample code')});");
  154. // Code2
  155. if (in_array('code2', $this->snippets))
  156. $cs->registerScript($scriptId.$c++,"jQuery('#".$this->editorId."-editor-code2').click(function(){if(this.value=='') return;insertTags('".$this->editorId."','~~~~bslashN['+this.value+']bslashN','bslashN~~~~bslashN','// Sample Ccode')});");
  157. // Add Lines
  158. if (in_array('addlines', $this->snippets))
  159. $cs->registerScript($scriptId.$c++,"jQuery('#".$this->editorId."-editor-addlines').click(function(){jQuery('#".$this->editorId."').attr('rows',jQuery('#".$this->editorId."').attr('rows')+5);});");
  160. // Remove Lines
  161. if (in_array('remlines', $this->snippets))
  162. $cs->registerScript($scriptId.$c++,"jQuery('#".$this->editorId."-editor-remlines').click(function(){jQuery('#".$this->editorId."').attr('rows',jQuery('#".$this->editorId."').attr('rows')-5);});");
  163. // Preview
  164. if (in_array('preview', $this->snippets))
  165. $cs->registerScript($scriptId.$c++,"jQuery('#".$this->editorId."-editor-preview').click(function(){jQuery('#".$this->editorId."').toggle();jQuery('#".$this->editorId."-preview').toggle();jQuery.ajax({type:'POST',url: '".$url."',data: jQuery(':parent form').serialize(),success:function(data){jQuery('#".$this->editorId."-preview').html(data);}});});");
  166. // Additional Snippets
  167. if(sizeof($this->additionalSnippets)>0) {
  168. $n=0;
  169. foreach($this->additionalSnippets as $name=>$additionalSnippet) {
  170. $ddId = $this->editorId."-editor-addS-".$n;
  171. $cs->registerScript($scriptId.$c++,"jQuery('#".$ddId."').change(function(){insertTags('".$this->editorId."','','',this.value);this.selectedIndex=0;});");
  172. $n++;
  173. }
  174. }
  175. } // }}}
  176. // {{{ resolveNameID
  177. /**
  178. * Generates input name and ID for a model attribute.
  179. * This method will update the HTML options by setting appropriate 'name' and 'id' attributes.
  180. * This method may also modify the attribute name if the name
  181. * contains square brackets (mainly used in tabular input).
  182. * @param CModel the data model
  183. * @param string the attribute
  184. * @param array the HTML options
  185. */
  186. public static function resolveNameID($model,&$attribute,&$htmlOptions)
  187. {
  188. if(!isset($htmlOptions['name']))
  189. $htmlOptions['name']=self::resolveName($model,$attribute);
  190. if(!isset($htmlOptions['id']))
  191. $htmlOptions['id']=self::getIdByName($htmlOptions['name']);
  192. else if($htmlOptions['id']===false)
  193. unset($htmlOptions['id']);
  194. } // }}}
  195. // {{{ getIdByName
  196. /**
  197. * Generates a valid HTML ID based the name.
  198. * @return string the ID generated based on name.
  199. */
  200. public static function getIdByName($name)
  201. {
  202. return str_replace(array('[]', '][', '[', ']'), array('', '_', '_', ''), $name);
  203. } // }}}
  204. // {{{ resolveName
  205. /**
  206. * Generates input name for a model attribute.
  207. * Note, the attribute name may be modified after calling this method if the name
  208. * contains square brackets (mainly used in tabular input) before the real attribute name.
  209. * @param CModel the data model
  210. * @param string the attribute
  211. * @return string the input name
  212. * @since 1.0.2
  213. */
  214. public static function resolveName($model,&$attribute)
  215. {
  216. if(($pos=strpos($attribute,'['))!==false)
  217. {
  218. if($pos!==0) // e.g. name[a][b]
  219. return get_class($model).'['.substr($attribute,0,$pos).']'.substr($attribute,$pos);
  220. if(($pos=strrpos($attribute,']'))!==false && $pos!==strlen($attribute)-1) // e.g. [a][b]name
  221. {
  222. $sub=substr($attribute,0,$pos+1);
  223. $attribute=substr($attribute,$pos+1);
  224. return get_class($model).$sub.'['.$attribute.']';
  225. }
  226. if(preg_match('/\](\w+\[.*)$/',$attribute,$matches))
  227. {
  228. $name=get_class($model).'['.str_replace(']','][',trim(strtr($attribute,array(']['=>']','['=>']')),']')).']';
  229. $attribute=$matches[1];
  230. return $name;
  231. }
  232. }
  233. else
  234. return get_class($model).'['.$attribute.']';
  235. } // }}}
  236. }
  237. /* vim: set ai sw=4 sts=4 et fdm=marker fdc=4: */