PageRenderTime 39ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/common/pheal/PhealFileCacheHashedNames.php

https://code.google.com/
PHP | 179 lines | 114 code | 7 blank | 58 comment | 9 complexity | 6622a37164823779c75ba88a201f2233 MD5 | raw file
Possible License(s): AGPL-1.0, LGPL-2.1
  1. <?php
  2. /*
  3. MIT License
  4. Copyright (c) 2011 Peter Petermann
  5. Permission is hereby granted, free of charge, to any person
  6. obtaining a copy of this software and associated documentation
  7. files (the "Software"), to deal in the Software without
  8. restriction, including without limitation the rights to use,
  9. copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. copies of the Software, and to permit persons to whom the
  11. Software is furnished to do so, subject to the following
  12. conditions:
  13. The above copyright notice and this permission notice shall be
  14. included in all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  17. OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  19. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  20. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22. OTHER DEALINGS IN THE SOFTWARE.
  23. */
  24. /**
  25. * Simple filecache for the xml
  26. */
  27. class PhealFileCacheHashedNames implements PhealCacheInterface
  28. {
  29. /**
  30. * path where to store the xml
  31. * @var string
  32. */
  33. protected $basepath;
  34. /**
  35. * various options for the filecache
  36. * valid keys are: delimiter, umask, umask_directory
  37. * @var array
  38. */
  39. protected $options = array(
  40. 'delimiter' => ':',
  41. 'umask' => 0666,
  42. 'umask_directory' => 0777
  43. );
  44. /**
  45. * construct PhealFileCache,
  46. * @param string $basepath optional string on where to store files, defaults to the current/users/home/.pheal/cache/
  47. * @param array $options optional config array, valid keys are: delimiter, umask, umask_directory
  48. */
  49. public function __construct($basepath = false, $options = array())
  50. {
  51. if(!$basepath)
  52. $basepath = getenv('HOME'). "/.pheal/cache/";
  53. $this->basepath = $basepath;
  54. // Windows systems don't allow : as part of the filename
  55. $this->options['delimiter'] = (strtoupper (substr(PHP_OS, 0,3)) == 'WIN') ? "#" : ":";
  56. // add options
  57. if(is_array($options) && count($options))
  58. $this->options = array_merge($this->options, $options);
  59. }
  60. /**
  61. * create a filename to use
  62. * @param int $userid
  63. * @param string $apikey
  64. * @param string $scope
  65. * @param string $name
  66. * @param array $args
  67. * @return string
  68. */
  69. protected function filename($userid, $apikey, $scope, $name, $args)
  70. {
  71. // secure input to make sure pheal don't write the files anywhere
  72. // user can define their own apikey/vcode
  73. // maybe this should be tweaked or hashed
  74. $regexp = "/[^a-z0-9,.-_=]/i";
  75. $userid = (int)$userid;
  76. $apikey = preg_replace($regexp,'_',$apikey);
  77. // build cache filename
  78. $argstr = "";
  79. foreach($args as $key => $val) {
  80. if(strlen($val) < 1)
  81. unset($args[$key]);
  82. elseif(!in_array(strtolower($key), array('userid','apikey','keyid','vcode')))
  83. $argstr .= preg_replace($regexp,'_',$key) . $this->options['delimiter'] . preg_replace($regexp,'_',$val) . $this->options['delimiter'];
  84. }
  85. $argstr = substr($argstr, 0, -1);
  86. $filename = "Request" . ($argstr ? "_" . md5($argstr) : "") . ".xml";
  87. $filepath = $this->basepath . ($userid ? "$userid/$apikey/$scope/$name/" : "public/public/$scope/$name/");
  88. if(!file_exists($filepath)) {
  89. // check write access
  90. if(!is_writable($this->basepath))
  91. throw new PhealException(sprintf("Cache directory '%s' isn't writeable", $filepath));
  92. // create cache folder
  93. $oldUmask = umask(0);
  94. mkdir($filepath, $this->options['umask_directory'], true);
  95. umask($oldUmask);
  96. } else {
  97. // check write access
  98. if(!is_writable($filepath))
  99. throw new PhealException(sprintf("Cache directory '%s' isn't writeable", $filepath));
  100. if(file_exists($filename) && !is_writeable($filename))
  101. throw new PhealException(sprintf("Cache file '%s' isn't writeable", $filename));
  102. }
  103. return $filepath . $filename;
  104. }
  105. /**
  106. * Load XML from cache
  107. * @param int $userid
  108. * @param string $apikey
  109. * @param string $scope
  110. * @param string $name
  111. * @param array $args
  112. */
  113. public function load($userid, $apikey, $scope, $name, $args)
  114. {
  115. $filename = $this->filename($userid, $apikey, $scope, $name, $args);
  116. if(!file_exists($filename))
  117. return false;
  118. $xml = file_get_contents($filename);
  119. if($this->validate_cache($xml))
  120. return $xml;
  121. return false;
  122. }
  123. /**
  124. * validate the cached xml if it is still valid. This contains a name hack
  125. * to work arround EVE API giving wrong cachedUntil values
  126. * @param string $xml
  127. * @return boolean
  128. */
  129. public function validate_cache($xml)
  130. {
  131. $tz = date_default_timezone_get();
  132. date_default_timezone_set("UTC");
  133. $xml = new SimpleXMLElement($xml);
  134. $dt = (int) strtotime($xml->cachedUntil);
  135. $time = time();
  136. date_default_timezone_set($tz);
  137. return (bool) ($dt > $time);
  138. }
  139. /**
  140. * Save XML from cache
  141. * @param int $userid
  142. * @param string $apikey
  143. * @param string $scope
  144. * @param string $name
  145. * @param array $args
  146. * @param string $xml
  147. */
  148. public function save($userid,$apikey,$scope,$name,$args,$xml)
  149. {
  150. $filename = $this->filename($userid, $apikey, $scope, $name, $args);
  151. $exists = file_exists($filename);
  152. // save content
  153. file_put_contents($filename, $xml);
  154. // chmod only new files
  155. if(!$exists)
  156. chmod($filename, $this->options['umask']);
  157. }
  158. }