SproutCMS

This is the code documentation for the SproutCMS project

source of /sprout/Helpers/Enc.php

  1. <?php
  2. /*
  3.  * Copyright (C) 2017 Karmabunny Pty Ltd.
  4.  *
  5.  * This file is a part of SproutCMS.
  6.  *
  7.  * SproutCMS is free software: you can redistribute it and/or modify it under the terms
  8.  * of the GNU General Public License as published by the Free Software Foundation, either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * For more information, visit <http://getsproutcms.com>.
  12.  */
  13.  
  14. namespace Sprout\Helpers;
  15.  
  16.  
  17.  
  18. /**
  19. * Encoding of data for various outputs
  20. **/
  21. class Enc
  22. {
  23.  
  24. /**
  25.   * Strip funky stuff from a string.
  26.   * Funky stuff is anything in the ASCII control plane (0x00 - 0x1F)
  27.   * Except tab, line feed, carriage return
  28.   **/
  29. public static function cleanfunky($value)
  30. {
  31. if (is_array($value)) return '';
  32. if (is_object($value)) return '';
  33. return preg_replace('![\x00-\x08\x0B\x0C\x0E-\x1F]!', '', (string) $value);
  34. }
  35.  
  36. /**
  37.   * Encoding for HTML
  38.   * Existing HTML entities in a string will be double-encoded
  39.   * @param string $value The text to encode. This should be plain (i.e. non-HTML) text
  40.   * @return string
  41.   * @example $html = Enc::html('A & B'); // returns A &amp; B
  42.   * @example $bad_html = Enc::html('A &amp; B'); // don't do this; returns A &amp;amp; B
  43.   */
  44. public static function html($value)
  45. {
  46. return htmlspecialchars(self::cleanfunky($value), ENT_COMPAT, 'UTF-8');
  47. }
  48.  
  49. /**
  50.   * Encoding for HTML, but safe from double-encoding of existing entities
  51.   * @param string $value The text to encode. This should be plain (i.e. non-HTML) text
  52.   * @return string
  53.   * @example $html = Enc::html('A & B'); // returns A &amp; B
  54.   * @example $html = Enc::html('A &amp; B'); // this is fine; returns A &amp; B
  55.   */
  56. public static function htmlNoDup($value)
  57. {
  58. return htmlspecialchars(self::cleanfunky($value), ENT_COMPAT, 'UTF-8', false);
  59. }
  60.  
  61. /**
  62.   * Encoding for XML
  63.   *
  64.   * @param string $value The value to encode
  65.   **/
  66. public static function xml($value)
  67. {
  68. $value = self::cleanfunky($value);
  69. $value = preg_replace('/[\s\r\n][\s\r\n]+/', "\n", $value);
  70. return htmlspecialchars($value, ENT_COMPAT, 'UTF-8');
  71. }
  72.  
  73. /**
  74.   * Encoding for a part of a URL (i.e. GET parameter value
  75.   *
  76.   * @param string $value The value to encode
  77.   **/
  78. public static function url($value)
  79. {
  80. return urlencode(self::cleanfunky($value));
  81. }
  82.  
  83. /**
  84.   * Encoding for ID or CLASS attributes
  85.   *
  86.   * @param string $value The value to encode
  87.   **/
  88. public static function id($value)
  89. {
  90. $value = self::cleanfunky($value);
  91. $value = trim($value);
  92. $value = str_replace(' ', '_', $value);
  93. $value = preg_replace('/[^a-z0-9_-]/i', '', $value);
  94.  
  95. $value = preg_replace('/__/', '_', $value);
  96. $value = trim($value, '_');
  97.  
  98. return $value;
  99. }
  100.  
  101. /**
  102.   * Encoding for going inside a JS string
  103.   *
  104.   * @param string $value The value to encode
  105.   **/
  106. public static function js($value)
  107. {
  108. $value = self::cleanfunky($value);
  109. $value = addslashes($value);
  110. $value = str_replace("\n", '\n', $value);
  111. $value = str_replace("\r", '\r', $value);
  112. $value = str_replace("\t", '\t', $value);
  113. return $value;
  114. }
  115.  
  116. /**
  117.   * Encoding for field name in a form element
  118.   *
  119.   * @param string $value The value to encode
  120.   **/
  121. public static function httpfield($value)
  122. {
  123. $value = self::cleanfunky($value);
  124. $value = str_replace(' ', '_', $value);
  125. $value = preg_replace('/[^a-zA-Z0-9:_.-]/', '', $value);
  126.  
  127. $value = preg_replace('/__/', '_', $value);
  128. $value = trim($value, '_');
  129.  
  130. return $value;
  131. }
  132.  
  133. /**
  134.   * Nice name of something when dealing with friendly URLs.
  135.   * This provides the backend for {@see Slug::create}
  136.   *
  137.   * @param string $value The value to encode
  138.   * @return string
  139.   */
  140. public static function urlname($value, $delimiter = '-')
  141. {
  142. $value = self::cleanfunky($value);
  143. $value = strtolower(trim($value, "&_- \t\n\r\0\x0B"));
  144.  
  145. // Basic replacements
  146. $value = str_replace('&', 'and', $value);
  147. $value = str_replace(array(' ', '-', '/', '\\'), '_', $value);
  148.  
  149. // Cleanup
  150. $value = preg_replace('/__/', '_', $value);
  151. $value = preg_replace('/[^a-z_0-9]/', '', $value);
  152. $value = trim($value, '_');
  153.  
  154. $value = str_replace('_', $delimiter, $value);
  155.  
  156. return $value;
  157. }
  158.  
  159. /**
  160.   * Returns the JS code needed to initialise a Date() object with the specified date.
  161.   * This should only be used for dates. For times or date-times, use a different function.
  162.   *
  163.   * From types:
  164.   * 'mysql' - a mysql-formatted date in the form YYYY-MM-DD
  165.   * 'array' - an array [ <day> , <month> , <year> ]
  166.   *
  167.   * @param string $value The value to convert.
  168.   * @param string $from What format the date was in origanally.
  169.   * @return string|null JavaScript snippet for the given date or NULL if the input value is invalid
  170.   **/
  171. public static function jsdate($value, $from = 'mysql')
  172. {
  173. $day = null;
  174. $month = null;
  175. $year = null;
  176.  
  177. switch ($from) {
  178. case 'mysql':
  179. $value = explode('-', self::cleanfunky($value));
  180. if (count($value) == 3) list ($year, $month, $day) = $value;
  181. break;
  182.  
  183. case 'array':
  184. if (is_array($value) and count($value) == 3) list ($day, $month, $year) = $value;
  185. break;
  186.  
  187. default:
  188. return null;
  189. break;
  190. }
  191.  
  192. if (!$day or !$month or !$year) return null;
  193.  
  194. // Convert a 2-digit year to a 4-digit year (just in case...)
  195. if (strlen($year) == 2) {
  196. if ($year >= 50) {
  197. $year = '19' . $year;
  198. } else {
  199. $year = '20' . $year;
  200. }
  201. }
  202.  
  203. $year = (int) $year;
  204. $month = (int) $month;
  205. $day = (int) $day;
  206.  
  207. if ($day == 0 or $month == 0 or $year == 0) return null;
  208.  
  209. return "new Date({$year}, {$month} - 1, {$day})";
  210. }
  211. }
  212.