PageRenderTime 26ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/engine/ICE/utils/webfont.php

https://github.com/PressCrew/infinity
PHP | 441 lines | 234 code | 38 blank | 169 comment | 23 complexity | 4a878136226ff9d53322943b15f3afd4 MD5 | raw file
Possible License(s): AGPL-1.0
  1. <?php
  2. /**
  3. * ICE API: web fonts helper class file
  4. *
  5. * @author Marshall Sorenson <marshall@presscrew.com>
  6. * @link http://infinity.presscrew.com/
  7. * @copyright Copyright (C) 2010-2011 Marshall Sorenson
  8. * @license http://www.gnu.org/licenses/gpl.html GPLv2 or later
  9. * @package ICE
  10. * @subpackage utils
  11. * @since 1.0
  12. */
  13. /**
  14. * Web fonts helper class
  15. *
  16. * @package ICE
  17. * @subpackage utils
  18. * @property-read string $path
  19. * @property-read string $url
  20. */
  21. class ICE_Webfont extends ICE_Base
  22. {
  23. /**
  24. * Singleton instance
  25. *
  26. * @var ICE_Webfont
  27. */
  28. private static $instance;
  29. /**
  30. * Web Font JSON result
  31. *
  32. * @var string
  33. */
  34. private $result;
  35. /**
  36. * Array of initialized services.
  37. *
  38. * @var array
  39. */
  40. private $services = array();
  41. /**
  42. * Constructor.
  43. *
  44. * @param integer $max_age
  45. */
  46. private function __construct( $max_age = 86400 )
  47. {
  48. // add google always (for now)
  49. $this->add_google();
  50. // grab result
  51. $this->result = $this->update();
  52. }
  53. /**
  54. * Return singleton instance
  55. *
  56. * @param integer $max_age
  57. * @return ICE_Webfont
  58. */
  59. public function instance( $max_age = 86400 )
  60. {
  61. if ( !self::$instance instanceof ICE_Webfont ) {
  62. self::$instance = new ICE_Webfont( $max_age );
  63. }
  64. return self::$instance;
  65. }
  66. /**
  67. * Add google service
  68. *
  69. * @return ICE_Webfont
  70. */
  71. public function add_google()
  72. {
  73. // has service been initialized?
  74. if ( false === isset( $this->services['google'] ) ) {
  75. // add to services registry
  76. $this->services['google'] = new ICE_Webfont_Service_Google();
  77. }
  78. // return self
  79. return $this;
  80. }
  81. /**
  82. * Fetch meta data for web font service
  83. *
  84. * @return string
  85. */
  86. public function update()
  87. {
  88. $data = array();
  89. // loop all services
  90. foreach ( $this->services as $service ) {
  91. // try to fetch data
  92. $raw = $service->fetch();
  93. // get any data?
  94. if ( $raw ) {
  95. // try to transform it
  96. $trans = $service->transform( $raw );
  97. // did transform work?
  98. if ( $trans ) {
  99. $data = array_merge( $data, $trans );
  100. }
  101. }
  102. }
  103. return json_encode( $data );
  104. }
  105. }
  106. /**
  107. * Web fonts service class
  108. *
  109. * @package ICE
  110. * @subpackage utils
  111. */
  112. abstract class ICE_Webfont_Service extends ICE_Base
  113. {
  114. // variants
  115. const VARIANT_N1 = 'n1';
  116. const VARIANT_N2 = 'n2';
  117. const VARIANT_N3 = 'n3';
  118. const VARIANT_N4 = 'n4';
  119. const VARIANT_N5 = 'n5';
  120. const VARIANT_N6 = 'n6';
  121. const VARIANT_N7 = 'n7';
  122. const VARIANT_N8 = 'n8';
  123. const VARIANT_N9 = 'n9';
  124. const VARIANT_I1 = 'i1';
  125. const VARIANT_I2 = 'i2';
  126. const VARIANT_I3 = 'i3';
  127. const VARIANT_I4 = 'i4';
  128. const VARIANT_I5 = 'i5';
  129. const VARIANT_I6 = 'i6';
  130. const VARIANT_I7 = 'i7';
  131. const VARIANT_I8 = 'i8';
  132. const VARIANT_I9 = 'i9';
  133. // subsets
  134. const SUBSET_LATIN = 'latin';
  135. const SUBSET_LATIN_EXT = 'latin-ext';
  136. const SUBSET_CYRILLIC = 'cyrillic';
  137. const SUBSET_CYRILLIC_EXT = 'cyrillic-ext';
  138. const SUBSET_GREEK = 'greek';
  139. const SUBSET_GREEK_EXT = 'greek-ext';
  140. const SUBSET_KHMER = 'khmer';
  141. const SUBSET_KHMER_EXT = 'khmer-ext';
  142. const SUBSET_VIETNAMESE = 'vietnamese';
  143. const SUBSET_VIETNAMESE_EXT = 'vietnamese-ext';
  144. /**
  145. * Name of the web font service
  146. *
  147. * @return string
  148. */
  149. abstract public function name();
  150. /**
  151. * Fetch meta data for web font service
  152. *
  153. * @return string
  154. */
  155. abstract public function fetch();
  156. /**
  157. * Normalize meta data for web font service
  158. *
  159. * @param string $data
  160. * @return array
  161. */
  162. abstract public function transform( $data );
  163. /**
  164. * Normalize font variant key for meta data
  165. *
  166. * @param string $variant
  167. * @return string
  168. */
  169. abstract protected function transform_variant_key( $variant );
  170. /**
  171. * Normalize font subset key for meta data
  172. *
  173. * @param string $subset
  174. * @return string
  175. */
  176. abstract protected function transform_subset_key( $subset );
  177. /**
  178. * Transform array of font variants
  179. *
  180. * @param array $variants
  181. * @return array
  182. */
  183. private function transform_variants( $variants )
  184. {
  185. // normalized data to return
  186. $data = array();
  187. // loop all variants
  188. foreach( $variants as $variant ) {
  189. // try to transform it
  190. $v_key = $this->transform_variant_key( $variant );
  191. // success?
  192. if ( $v_key ) {
  193. $data[$v_key] = $variant;
  194. }
  195. }
  196. return $data;
  197. }
  198. /**
  199. * Transform array of font subsets
  200. *
  201. * @param array $subsets
  202. * @return array
  203. */
  204. private function transform_subsets( $subsets )
  205. {
  206. // normalized data to return
  207. $data = array();
  208. // loop all subsets
  209. foreach( $subsets as $subset ) {
  210. // try to transform it
  211. $s_key = $this->transform_subset_key( $subset );
  212. // success?
  213. if ( $s_key ) {
  214. $data[$s_key] = $subset;
  215. }
  216. }
  217. return $data;
  218. }
  219. /**
  220. * Return a font meta "package" with normalized keys
  221. *
  222. * @param string $service
  223. * @param string $family
  224. * @param array $variants
  225. * @param array $subsets
  226. * @return array
  227. */
  228. protected function font_metadata( $service, $family, $variants, $subsets )
  229. {
  230. // trans variants and subsets
  231. $variants_trans = $this->transform_variants( $variants );
  232. $subsets_trans = $this->transform_subsets( $subsets );
  233. // successful transformations?
  234. if ( $variants_trans && $subsets_trans ) {
  235. // return normalized meta data
  236. return array(
  237. 'service' => $service,
  238. 'family' => $family,
  239. 'variants' => $variants_trans,
  240. 'subsets' => $subsets_trans
  241. );
  242. } else {
  243. return null;
  244. }
  245. }
  246. }
  247. /**
  248. * Google web fonts service class
  249. *
  250. * @package ICE
  251. * @subpackage utils
  252. */
  253. class ICE_Webfont_Service_Google extends ICE_Webfont_Service
  254. {
  255. /**
  256. * Google Web Fonts API URL
  257. *
  258. * Don't be a dick. Get your own API key from Google, they are free.
  259. */
  260. const API_URL = 'https://www.googleapis.com/webfonts/v1/webfonts?key=AIzaSyBrehr0y7NPVDFbYxbRIV_MYMWZhi9Sur0';
  261. /**
  262. */
  263. public function name()
  264. {
  265. return 'google';
  266. }
  267. /**
  268. */
  269. public function fetch()
  270. {
  271. // try to open url
  272. $result = wp_remote_fopen( self::API_URL );
  273. // success?
  274. if ( $result !== false ) {
  275. return $result;
  276. } else {
  277. return null;
  278. }
  279. }
  280. /**
  281. */
  282. public function transform( $data )
  283. {
  284. // try to decode it
  285. $array = json_decode( $data, true );
  286. // is array and has items?
  287. if ( isset( $array['items'] ) && is_array( $array['items'] ) && count( $array['items'] ) ) {
  288. // data to return
  289. $data = array();
  290. // loop all items
  291. foreach( $array['items'] as $item ) {
  292. // try to transform each one
  293. $trans = $this->transform_item( $item );
  294. // success?
  295. if ( $trans ) {
  296. array_push( $data, $trans );
  297. }
  298. }
  299. // all done
  300. return $data;
  301. }
  302. return null;
  303. }
  304. /**
  305. * @param array $item
  306. * @return array|false
  307. */
  308. private function transform_item( $item )
  309. {
  310. if (
  311. ( isset( $item['family'] ) && strlen( $item['family'] ) ) &&
  312. ( isset( $item['variants'] ) && is_array( $item['variants'] ) && count( $item['variants'] ) ) &&
  313. ( isset( $item['subsets'] ) && is_array( $item['subsets'] ) && count( $item['subsets'] ) )
  314. ) {
  315. return $this->font_metadata( $this->name(), $item['family'], $item['variants'], $item['subsets'] );
  316. }
  317. return null;
  318. }
  319. /**
  320. */
  321. protected function transform_variant_key( $variant )
  322. {
  323. // normalize the variant
  324. switch ( $variant ) {
  325. case 'regular':
  326. return self::VARIANT_N4;
  327. case 'bold':
  328. return self::VARIANT_N7;
  329. case '100':
  330. return self::VARIANT_N1;
  331. case '200':
  332. return self::VARIANT_N2;
  333. case '300':
  334. return self::VARIANT_N3;
  335. case '400':
  336. return self::VARIANT_N4;
  337. case '500':
  338. return self::VARIANT_N5;
  339. case '600':
  340. return self::VARIANT_N6;
  341. case '700':
  342. return self::VARIANT_N7;
  343. case '800':
  344. return self::VARIANT_N8;
  345. case '900':
  346. return self::VARIANT_N9;
  347. case 'italic':
  348. return self::VARIANT_I4;
  349. case 'bolditalic':
  350. return self::VARIANT_I7;
  351. case '100italic':
  352. return self::VARIANT_I1;
  353. case '200italic':
  354. return self::VARIANT_I2;
  355. case '300italic':
  356. return self::VARIANT_I3;
  357. case '400italic':
  358. return self::VARIANT_I4;
  359. case '500italic':
  360. return self::VARIANT_I5;
  361. case '600italic':
  362. return self::VARIANT_I6;
  363. case '700italic':
  364. return self::VARIANT_I7;
  365. case '800italic':
  366. return self::VARIANT_I8;
  367. case '900italic':
  368. return self::VARIANT_I9;
  369. default:
  370. return null;
  371. }
  372. }
  373. /**
  374. */
  375. protected function transform_subset_key( $subset )
  376. {
  377. // normalize the subset
  378. switch ( $subset ) {
  379. case 'latin':
  380. return self::SUBSET_LATIN;
  381. case 'latin-ext':
  382. return self::SUBSET_LATIN_EXT;
  383. case 'cyrillic':
  384. return self::SUBSET_CYRILLIC;
  385. case 'cyrillic-ext':
  386. return self::SUBSET_CYRILLIC_EXT;
  387. case 'greek':
  388. return self::SUBSET_GREEK;
  389. case 'greek-ext':
  390. return self::SUBSET_GREEK_EXT;
  391. case 'khmer':
  392. return self::SUBSET_KHMER;
  393. case 'khmer-ext':
  394. return self::SUBSET_KHMER_EXT;
  395. case 'vietnamese':
  396. return self::SUBSET_VIETNAMESE;
  397. case 'vietnamese-ext':
  398. return self::SUBSET_VIETNAMESE_EXT;
  399. default:
  400. return null;
  401. }
  402. }
  403. }