PageRenderTime 49ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/attributes/class.atkcolorpickerattribute.inc

https://github.com/ibuildingsnl/ATK
PHP | 489 lines | 258 code | 56 blank | 175 comment | 57 complexity | 500609b8eb3bd40875c351eea35d1b37 MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, MPL-2.0-no-copyleft-exception, LGPL-3.0
  1. <?php
  2. /**
  3. * This file is part of the Achievo ATK distribution.
  4. * Detailed copyright and licensing information can be found
  5. * in the doc/COPYRIGHT and doc/LICENSE files which should be
  6. * included in the distribution.
  7. *
  8. * @todo The rgb color support in check_color() only works if another argument 'rgb'
  9. * is passed, which never happens because only 1 argument is passed to that method from the
  10. * atkColorPickerAttribute.
  11. *
  12. * @todo The colorpicker appears to support values such as 'red' to be entered in the popup
  13. * (the edit of the attribute shows the correct color) although the value never passes the
  14. * validation.
  15. *
  16. * @todo The colorpicker supports the first # to be optionally entered, but the edit of
  17. * the attribute does not show the correct color.
  18. *
  19. * @package atk
  20. * @subpackage attributes
  21. *
  22. * @copyright (c)2000-2004 Ibuildings.nl BV
  23. * @license http://www.achievo.org/atk/licensing ATK Open Source License
  24. *
  25. * @version $Revision: 6334 $
  26. * $Id$
  27. */
  28. /** @internal includes and defines **/
  29. useattrib("atkattribute");
  30. define("CP_COLORMODE_DEFAULT" ,0);
  31. define("CP_COLORMODE_HEX6" ,1);
  32. /**
  33. * Draws one colored <td>gif</td> box with javascript parameters in the desired height,width and color
  34. * @access private
  35. */
  36. function drawTD($field,$color,$colHeight,$colWidth,$extern=0)
  37. {
  38. $row ="<td width='".$colWidth."' bgcolor='$color'>";
  39. if ($extern !=0)
  40. {
  41. $row .='<A href ="javascript:remotePicker';
  42. }
  43. else
  44. {
  45. $row .='<A href ="javascript:picker';
  46. }
  47. $row .="('".$field."','".$color."')";
  48. $row .='" title="'.atktext("color", "atk").': '.$color.'"><IMG SRC="'.atkconfig('atkroot').'atk/images/dummy.gif" border=0 width='.$colWidth.' height='.$colHeight.' alt="-X-"></a></td>';
  49. $row .= "\n";
  50. return $row;
  51. }
  52. /**
  53. * Returns a string with the entire colorPicker matrix
  54. * @access private
  55. */
  56. function colorMatrix($colHeight,$colWidth,$field,$extern=0,$userColors)
  57. {
  58. $webColors = array ("00", "11", "22", "33", "44","55","66","77","88","99","AA","BB","CC","DD","EE","FF");
  59. $stdColors = array("000000","A4358E","C79476","6699cc","cc6699","669933","ff9900","cccc99","663399","5dabdd","cafe00","ffcc33"); // standard favorite colors
  60. $nrColors = count($webColors);
  61. // Mix RED / BLUE (16x16 = 256 items)
  62. $matrix_rb = '<table width ="100%" border="0" cellspacing="1" cellpadding="0">';
  63. $matrix_rb .= '<tr>';
  64. for ($i=0;$i<$nrColors;$i++)
  65. {
  66. for ($j=0;$j<$nrColors;$j++)
  67. {
  68. $color = "#".$webColors[$i].$webColors[$j]."00";
  69. $matrix_rb .= drawTD($field, $color, $colHeight, $colWidth, $extern);
  70. }
  71. $matrix_rb .= '</tr><tr>';
  72. }
  73. $matrix_rb .= '</tr></table>';
  74. // Mix RED / GREEN (16x16 = 256 items)
  75. $matrix_rg = '<table width ="100%" border="0" cellspacing="1" cellpadding="0">';
  76. $matrix_rg .= '<tr>';
  77. for ($i=0;$i<$nrColors;$i++)
  78. {
  79. for ($j=0;$j<$nrColors;$j++)
  80. {
  81. $color = "#".$webColors[$i]."00".$webColors[$j];
  82. $matrix_rg .= drawTD($field, $color, $colHeight, $colWidth, $extern);
  83. }
  84. $matrix_rg .= '</tr><tr>';
  85. }
  86. $matrix_rg .= '</tr></table>';
  87. // Mix GREEN / BLUE (16x16 = 256 items)
  88. $matrix_gb = '<table width ="100%" border="0" cellspacing="1" cellpadding="0">';
  89. $matrix_gb .= '<tr>';
  90. for ($i=0;$i<$nrColors;$i++)
  91. {
  92. for ($j=0;$j<$nrColors;$j++)
  93. {
  94. $color = "#00".$webColors[$i].$webColors[$j];
  95. $matrix_gb .= drawTD($field, $color, $colHeight, $colWidth, $extern);
  96. }
  97. $matrix_gb .= '</tr><tr>';
  98. }
  99. $matrix_gb .= '</tr></table>';
  100. $matrix_red = '<table width = "100%" border="0" cellspacing="1" cellpadding="0"><tr>';
  101. $matrix_green = '<table width = "100%" border="0" cellspacing="1" cellpadding="0"><tr>';
  102. $matrix_blue = '<table width = "100%" border="0" cellspacing="1" cellpadding="0"><tr>';
  103. $matrix_grey = '<table width = "100%" border="0" cellspacing="1" cellpadding="0"><tr>';
  104. // Primary color shades and grayscales
  105. for ($i=0;$i<$nrColors;$i++)
  106. {
  107. $matrix_red .= drawTD($field, "#".$webColors[$i]."0000", $colHeight, $colWidth, $extern);
  108. $matrix_green .= drawTD($field, "#00".$webColors[$i]."00", $colHeight, $colWidth, $extern);
  109. $matrix_blue .= drawTD($field, "#0000".$webColors[$i], $colHeight, $colWidth, $extern);
  110. $matrix_grey .= drawTD($field, "#".$webColors[$i].$webColors[$i].$webColors[$i], $colHeight, $colWidth, $extern);
  111. }
  112. $matrix_red .= '</tr></table>';
  113. $matrix_green .= '</tr></table>';
  114. $matrix_blue .= '</tr></table>';
  115. $matrix_grey .= '</tr></table>';
  116. // Check optional user colors
  117. if (trim($userColors) != "")
  118. {
  119. $tmpColors = explode("|", $userColors);
  120. $matrix_user = '<table border="0" cellspacing="1" cellpadding="0"><tr>';
  121. for ($i=0;$i<=count($tmpColors)-1;$i++)
  122. {
  123. $dummy = $tmpColors[$i];
  124. if (substr($dummy,0,1) != "#")
  125. {
  126. $dummy = "#".$dummy;
  127. }
  128. $matrix_user .= drawTD($field, $dummy, $colHeight, $colWidth, $extern);
  129. }
  130. $matrix_user .= '</tr></table>';
  131. }
  132. else
  133. {
  134. $matrix_user = '';
  135. }
  136. return array($matrix_rb, $matrix_rg, $matrix_gb, $matrix_red, $matrix_green, $matrix_blue, $matrix_grey, $matrix_user);
  137. }
  138. /**
  139. * The atkColorPickerAttribute class represents an attribute of an atkNode.
  140. * An atkColorPickerAttribute shows a box with 10 user defined colors and 90 pre-defined colors
  141. * from wich the user can select a color or enter the hexcode in a textfield
  142. *
  143. * flags: AF_POPUP opens a popup screen with colorpicker instead of drawing under the input field
  144. * @todo There are many global functions in the class file
  145. * class.atkcolorpickerattribute.inc. These should be moved to private
  146. * class methods.
  147. * @author Rene Bakx <rene@ibuildings.nl>
  148. * @package atk
  149. * @subpackage attributes
  150. *
  151. */
  152. class atkColorPickerAttribute extends atkAttribute
  153. {
  154. var $m_userColors;
  155. var $m_currentColor;
  156. var $m_colorMode = CP_COLORMODE_DEFAULT;
  157. /**
  158. * Constructor
  159. *
  160. * <b>Example:</b>
  161. * $this->add(new atkColorPickerAttribute("naam",Array,AF_OBLIGATORY|AF_POPUP));
  162. * @param string $name Name of the attribute
  163. * @param array $userColors Array with max. 12 user defined colors
  164. * @param int $flags Flags for the attribute
  165. */
  166. function atkColorPickerAttribute($name, $userColors="", $flags = 0)
  167. {
  168. // Call baseclass constructor. We set 10 as default size. An html
  169. // colorvalue (#ffffaa) is 7 chars, but with 10 chars, we can also
  170. // save named colors like 'white' etc.
  171. $this->atkAttribute($name, $flags, 10);
  172. $this->m_userColors = $userColors;
  173. }
  174. /**
  175. * Retrieve the list of searchmodes supported by the attribute.
  176. *
  177. * @return array List of supported searchmodes
  178. */
  179. function getSearchModes()
  180. {
  181. // exact match and substring search should be supported by any database.
  182. // (the LIKE function is ANSI standard SQL, and both substring and wildcard
  183. // searches can be implemented using LIKE)
  184. // Possible values
  185. //"regexp","exact","substring", "wildcard","greaterthan","greaterthanequal","lessthan","lessthanequal"
  186. return array();
  187. }
  188. /**
  189. * Set the colormode (The value is checked according to the colormode that is set).
  190. *
  191. * Supported values are:
  192. * default (rgb, hex with 6 characters digits, hex with 3 characters, text etc.).
  193. * hex6 (only 6 digit hexadecimal)
  194. *
  195. * Other modes are not supported yet, but could be implemented in the future.
  196. *
  197. * @param String $mode
  198. */
  199. function setColorMode($mode = NULL)
  200. {
  201. if ($mode === NULL)
  202. $this->m_colorMode = CP_COLORMODE_DEFAULT;
  203. else
  204. $this->m_colorMode = $mode;
  205. }
  206. /**
  207. * Get the colormode for this colorpicker.
  208. *
  209. * @return unknown
  210. */
  211. function getColorMode()
  212. {
  213. return $this->m_colorMode;
  214. }
  215. /**
  216. * Returns a piece of html code that can be used in a form to edit this
  217. * attribute's value.
  218. *
  219. * @param array $record The record that holds the value for this attribute.
  220. * @param String $fieldprefix The fieldprefix to put in front of the name
  221. * of any html form element for this attribute.
  222. * @param String $mode The mode we're in ('add' or 'edit')
  223. * @return String A piece of htmlcode for editing this attribute
  224. */
  225. function edit($record="", $fieldprefix="", $mode="")
  226. {
  227. $page = &atkPage::getInstance();
  228. $page->register_script(atkconfig("atkroot")."atk/javascript/newwindow.js");
  229. $page->register_script(atkconfig("atkroot")."atk/javascript/colorpicker.js");
  230. $colHeight = "11";
  231. $colWidth = "11";
  232. $formRef = $this->fieldName();
  233. if ($this->m_currentColor == "")
  234. {
  235. $this->m_currentColor = atkArrayNvl($record, $this->fieldName(), "");
  236. }
  237. $colorField = '<input type="hidden" name="'.$fieldprefix.$this->formName().'" id="'.$fieldprefix.$this->formName().'" value="'.$this->m_currentColor.'" size="7" maxlength="7">';
  238. if ($this->m_userColors !="")
  239. {
  240. $temp = $this->m_userColors;
  241. $userCol = implode("|",$temp);
  242. }
  243. else
  244. {
  245. $userCol = "";
  246. }
  247. if (trim($this->m_currentColor) == "")
  248. {
  249. $selectImg = atkconfig("atkroot")."atk/images/select_color_off.gif";
  250. $alt = atkText("no_color_selected", "atk");
  251. }
  252. else
  253. {
  254. $selectImg = atkconfig("atkroot")."atk/images/select_color_on.gif";
  255. $alt = $this->m_currentColor;
  256. }
  257. // check if $this->m_currentColor starts with an # (to avoid parted url)
  258. if (substr($this->m_currentColor,0,1) == "#")
  259. {
  260. $urlColor = substr($this->m_currentColor,1);
  261. }
  262. else
  263. {
  264. $urlColor = $this->m_currentColor;
  265. }
  266. $url = atkPopup('atk/popups/colorpicker.inc','field='.$fieldprefix.$this->fieldName().'&activecolor='.$urlColor.'&usercol='.$userCol,'colorPicker',315,1000,'no','no');
  267. $text = '<a href="javascript:void(0);" onclick="'.$url.'; return false;"><img name="img_'.$fieldprefix.$this->fieldName().'" id="img_'.$fieldprefix.$this->fieldName().'" src="'.$selectImg.'" border="0" alt="'.$alt.'" style="background-color: '.$alt.';"></a>'.$colorField;
  268. $result = '<table cellpadding="0" cellspacing="0" border="0" width="35" height="21" align="left"><tr><td id="example_'.$fieldprefix.$this->fieldName().'" name="example_'.$fieldprefix.$this->fieldName().'" style="padding:0px;" valign="top" align="left" bgcolor="'.$this->m_currentColor.'">'.$text.'</td></tr></table>';
  269. return $result;
  270. }
  271. /**
  272. * Checks if a value is valid.
  273. *
  274. * @param array $record The record that holds the value for this
  275. * attribute. If an error occurs, the error will
  276. * be stored in the 'atkerror' field of the record.
  277. * @param String $mode The mode for which should be validated ("add" or
  278. * "update")
  279. */
  280. function validate(&$record, $mode)
  281. {
  282. $color = $record[$this->fieldName()];
  283. if(!$this->check_color($color))
  284. atkTriggerError($record, $this, 'error_invalid_color');
  285. }
  286. /**
  287. * Function to check if a color is correct (default is hex colors)
  288. * Example:
  289. * check_color("#zff, "hex"")
  290. * check_color("rgb(204,255,0)", "rgb")
  291. * @access private
  292. * @return boolean valid color or not
  293. */
  294. function check_color()
  295. {
  296. $numargs = func_num_args();
  297. if (!$this->checkNumArgs($numargs))
  298. return false;
  299. $colors = func_get_arg(0);
  300. $type = ($numargs == 2) ? func_get_arg(1) : 'hex';
  301. if (!is_string($colors) || !$this->checkTypeAndMode($type))
  302. return false;
  303. // color types -
  304. // hex - hexidecimal value in form of #XXX, XXX, #XXXXXX, or XXXXXX
  305. // rgb - rgb value in form of rgb(X,Y,Z);
  306. if($type == "hex")
  307. {
  308. $colors = strtolower(str_replace("#", "", $colors));
  309. return $this->checkHexColor($colors);
  310. }
  311. elseif($type == "rgb")
  312. {
  313. $error = 0;
  314. // check the start and the end of the color code to make sure it's a valid form
  315. if((substr($colors, 0, 4)) != "rgb(" or substr($colors, -1) != ")"){ $error++; }
  316. else
  317. {
  318. $len = strlen($colors);
  319. // the full length - 5 characters to make up for the "rgb(" and the ")" - 5 characters total
  320. $lenone = $len - 5;
  321. // $colors is now only the values and the commas (",") that seperate them
  322. // rgb(51,102,153) is now 51,102,153 - we need this to explode the data in the next step
  323. $colors = substr($colors, 4, $lenone);
  324. // explode the color substring - should be in X,Y,Z format now.
  325. // $extras takes any characters more than the X,Y,Z format.
  326. list($r, $g, $b, $extras) = explode(",",$colors);
  327. // Check the rgb values that were just exploded.
  328. if($r < 0 or $r > 255 or $g < 0 or $g > 255 or $b < 0 or $b > 255) { $error++; }
  329. // Make sure that none of the values are blank - prevents rgb(12) or rgb(12,12) from being valid
  330. if($r == "" or $g == "" or $b == ""){ $error++; }
  331. // \D in the character class means any non-decimal character except newline
  332. $rt = preg_match_all("[\D]", $r, $matches);
  333. $gt = preg_match_all("[\D]", $g, $matches);
  334. $bt = preg_match_all("[\D]", $b, $matches);
  335. // If we matched any characters above the values are not valid.
  336. // Also is there is anything in $extras - the whole color code is an invalid form!
  337. if($rt > 0 or $gt > 0 or $bt > 0 or $extras != ""){ $error++; }
  338. // If there are any errors then the color is not valid, return false, otherwise
  339. // we're okay and we retun true
  340. if($error > 0) { return false; } else { return true; }
  341. }
  342. }
  343. else
  344. {
  345. atkerror("Error in function check_color(): Invalid argument for color type.");
  346. return false;
  347. }
  348. }
  349. /**
  350. * Check the amount of arguments that were passed
  351. *
  352. * @param Integer $numargs The number of arguments that were passed
  353. * @return Boolean True if the number of arguments is valid, False otherwise
  354. */
  355. function checkNumArgs($numargs)
  356. {
  357. if($numargs < 1)
  358. {
  359. atkerror("Error in function check_color(): No arguments passed to function.");
  360. return false;
  361. }
  362. if($numargs > 2)
  363. {
  364. atkerror("Error in function check_color(): Too many arguments passed to function.");
  365. return false;
  366. }
  367. return true;
  368. }
  369. /**
  370. * Check if the determined type matches the mode that was set.
  371. *
  372. * @param String $type
  373. * @return True if valid, false otherwise
  374. */
  375. function checkTypeAndMode($type)
  376. {
  377. // For hex types, the colormode must be default or hex6
  378. if (($type == 'hex') &&
  379. in_array($this->getColorMode(), array(CP_COLORMODE_DEFAULT, CP_COLORMODE_HEX6)))
  380. {
  381. return true;
  382. }
  383. // For rgb types, the colormode must be default.
  384. if (($type == 'rgb') &&
  385. ($this->getColorMode() == CP_COLORMODE_DEFAULT))
  386. {
  387. return true;
  388. }
  389. return false;
  390. }
  391. /**
  392. * Check the hex color (also based on the mode).
  393. *
  394. * @param String $colors
  395. * @return True if valid, false otherwise
  396. */
  397. function checkHexColor($colors)
  398. {
  399. // \d is all decimal digits (0-9)
  400. $t = preg_match_all("([\da-f])", $colors, $matches);
  401. $length = strlen($colors);
  402. // Have to match the preg_match_all with the length to prevent incorrect results
  403. // else 3 matches in a 6 character code would make something like 123x98 valid
  404. $isHex3 = ($t == 3 && $length == 3);
  405. $isHex6 = ($t == 6 && $length == 6);
  406. if ($isHex3)
  407. {
  408. return $this->getColorMode() != CP_COLORMODE_HEX6;
  409. }
  410. // If the color is not hex3, it must be hex6 otherwise this check fails.
  411. return $isHex6;
  412. }
  413. /**
  414. * Return the database field type of the attribute.
  415. *
  416. * Note that the type returned is a 'generic' type. Each database
  417. * vendor might have his own types, therefor, the type should be
  418. * converted to a database specific type using $db->fieldType().
  419. *
  420. * If the type was read from the table metadata, that value will
  421. * be used. Else, the attribute will analyze its flags to guess
  422. * what type it should be. If AF_AUTO_INCREMENT is set, the field
  423. * is probaly "number". If not, it's probably "string".
  424. *
  425. * @return String The 'generic' type of the database field for this
  426. * attribute.
  427. */
  428. function dbFieldType()
  429. {
  430. return "string";
  431. }
  432. }
  433. ?>