PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/common/libraries/plugin/phpfreechat/src/containers/file.class.php

https://bitbucket.org/chamilo/chamilo-dev/
PHP | 314 lines | 215 code | 46 blank | 53 comment | 45 complexity | f88ce855b154d3806c2b34d83e5900cb MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, LGPL-3.0, GPL-3.0, MIT
  1. <?php
  2. /**
  3. * file.class.php
  4. *
  5. * Copyright ??? 2006 Stephane Gully <stephane.gully@gmail.com>
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the
  19. * Free Software Foundation, 51 Franklin St, Fifth Floor,
  20. * Boston, MA 02110-1301 USA
  21. */
  22. require_once dirname(__FILE__) . "/../pfccontainerinterface.class.php";
  23. /**
  24. * pfcContainer_File is a concret container which stock data into files
  25. *
  26. * @author Stephane Gully <stephane.gully@gmail.com>
  27. */
  28. class pfcContainer_File extends pfcContainerInterface
  29. {
  30. var $_users = array("nickid" => array(), "timestamp" => array());
  31. var $_meta = array();
  32. function __construct()
  33. {
  34. pfcContainerInterface :: __construct();
  35. }
  36. function loadPaths(&$c)
  37. {
  38. if (! isset($c->container_cfg_chat_dir) || $c->container_cfg_chat_dir == '')
  39. $c->container_cfg_chat_dir = $c->data_private_path . "/chat";
  40. if (! isset($c->container_cfg_server_dir) || $c->container_cfg_server_dir == '')
  41. $c->container_cfg_server_dir = $c->container_cfg_chat_dir . "/s_" . $c->serverid;
  42. }
  43. function getDefaultConfig()
  44. {
  45. $cfg = pfcContainerInterface :: getDefaultConfig();
  46. $cfg["chat_dir"] = ''; // will be generated from the other parameters into the init step
  47. $cfg["server_dir"] = ''; // will be generated from the other parameters into the init step
  48. return $cfg;
  49. }
  50. function init(&$c)
  51. {
  52. $errors = pfcContainerInterface :: init($c);
  53. // generate the container parameters from other config parameters
  54. $this->loadPaths($c);
  55. $errors = array_merge($errors, @test_writable_dir($c->container_cfg_chat_dir, "container_cfg_chat_dir"));
  56. $errors = array_merge($errors, @test_writable_dir($c->container_cfg_server_dir, "container_cfg_chat_dir/serverid"));
  57. // test the filemtime php function because it doesn't work on special filesystem
  58. // example : NFS, VZFS
  59. $filename = $c->data_private_path . '/filemtime.test';
  60. $timetowait = 2;
  61. if (is_writable(dirname($filename)))
  62. {
  63. file_put_contents($filename, 'some-data1-' . time());
  64. clearstatcache();
  65. $time1 = filemtime($filename);
  66. sleep($timetowait);
  67. file_put_contents($filename, 'some-data2-' . time());
  68. clearstatcache();
  69. $time2 = filemtime($filename);
  70. unlink($filename);
  71. if ($time2 - $time1 != $timetowait)
  72. $errors[] = "filemtime php fuction is not usable on your filesystem. Please do not use the 'file' container (try the 'mysql' container) or swith to another filesystem type.";
  73. }
  74. // test the LOCK_EX feature because it doesn't work on special filsystem like NFS
  75. $filename = $c->data_private_path . '/filemtime.test';
  76. if (is_writable(dirname($filename)))
  77. {
  78. $data1 = time();
  79. //file_put_contents($filename, $data1, LOCK_EX);
  80. file_put_contents($filename, $data1);
  81. $data2 = file_get_contents($filename);
  82. if ($data1 != $data2)
  83. {
  84. }
  85. //$errors[] = "LOCK_EX feature is not usable on your filesystem. Please do not use the 'file' container (try the 'mysql' container) or swith to another filesystem type.";
  86. }
  87. return $errors;
  88. }
  89. function setMeta($group, $subgroup, $leaf, $leafvalue = NULL)
  90. {
  91. $c = & pfcGlobalConfig :: Instance();
  92. // create directories
  93. $dir_base = $c->container_cfg_server_dir;
  94. $dir = $dir_base . '/' . $group . '/' . $subgroup;
  95. if (! is_dir($dir))
  96. mkdir_r($dir);
  97. // create or replace metadata file
  98. $leaffilename = $dir . "/" . $leaf;
  99. $leafexists = file_exists($leaffilename);
  100. if ($leafvalue == NULL)
  101. {
  102. touch($leaffilename);
  103. }
  104. else
  105. {
  106. //file_put_contents($leaffilename, $leafvalue, LOCK_EX);
  107. file_put_contents($leaffilename, $leafvalue);
  108. }
  109. // store the value in the memory cache
  110. //@todo
  111. // $this->_meta[$enc_type][$enc_subtype][$enc_key] = $value;
  112. if ($leafexists)
  113. return 1; // value overwritten
  114. else
  115. return 0; // value created
  116. }
  117. function getMeta($group, $subgroup = null, $leaf = null, $withleafvalue = false)
  118. {
  119. $c = & pfcGlobalConfig :: Instance();
  120. // read data from metadata file
  121. $ret = array();
  122. $ret["timestamp"] = array();
  123. $ret["value"] = array();
  124. $dir_base = $c->container_cfg_server_dir;
  125. $dir = $dir_base . '/' . $group;
  126. if ($subgroup == NULL)
  127. {
  128. if (is_dir($dir))
  129. {
  130. $dh = opendir($dir);
  131. while (false !== ($file = readdir($dh)))
  132. {
  133. if ($file == "." || $file == "..")
  134. continue; // skip . and .. generic files
  135. $ret["timestamp"][] = filemtime($dir . '/' . $file);
  136. $ret["value"][] = $file;
  137. }
  138. closedir($dh);
  139. }
  140. return $ret;
  141. }
  142. $dir .= '/' . $subgroup;
  143. if ($leaf == NULL)
  144. {
  145. if (is_dir($dir))
  146. {
  147. $dh = opendir($dir);
  148. while (false !== ($file = readdir($dh)))
  149. {
  150. if ($file == "." || $file == "..")
  151. continue; // skip . and .. generic files
  152. $ret["timestamp"][] = filemtime($dir . '/' . $file);
  153. $ret["value"][] = $file;
  154. }
  155. closedir($dh);
  156. }
  157. return $ret;
  158. }
  159. $leaffilename = $dir . "/" . $leaf;
  160. if (! file_exists($leaffilename))
  161. return $ret;
  162. if ($withleafvalue)
  163. $ret["value"][] = file_get_contents_flock($leaffilename);
  164. else
  165. $ret["value"][] = NULL;
  166. $ret["timestamp"][] = filemtime($leaffilename);
  167. return $ret;
  168. }
  169. function incMeta($group, $subgroup, $leaf)
  170. {
  171. $c = & pfcGlobalConfig :: Instance();
  172. // create directories
  173. $dir_base = $c->container_cfg_server_dir;
  174. $dir = $dir_base . '/' . $group . '/' . $subgroup;
  175. if (! is_dir($dir))
  176. mkdir_r($dir);
  177. // create or replace metadata file
  178. $leaffilename = $dir . "/" . $leaf;
  179. // create return array
  180. $ret = array();
  181. $ret["timestamp"] = array();
  182. $ret["value"] = array();
  183. // read and increment data from metadata file
  184. clearstatcache();
  185. if (file_exists($leaffilename))
  186. {
  187. $fh = fopen($leaffilename, 'r+');
  188. for($i = 0; $i < 10; $i ++) // Try 10 times until an exclusive lock can be obtained
  189. {
  190. //if (flock($fh, LOCK_EX))
  191. {
  192. $leafvalue = chop(fread($fh, filesize($leaffilename)));
  193. $leafvalue ++;
  194. rewind($fh);
  195. fwrite($fh, $leafvalue);
  196. fflush($fh);
  197. ftruncate($fh, ftell($fh));
  198. flock($fh, LOCK_UN);
  199. break;
  200. }
  201. // If flock is working properly, this will never be reached
  202. $delay = rand(0, pow(2, ($i + 1)) - 1) * 5000; // Exponential backoff
  203. usleep($delay);
  204. }
  205. fclose($fh);
  206. }
  207. else
  208. {
  209. $leafvalue = "1";
  210. //file_put_contents($leaffilename, $leafvalue, LOCK_EX);
  211. file_put_contents($leaffilename, $leafvalue);
  212. }
  213. $ret["value"][] = $leafvalue;
  214. $ret["timestamp"][] = filemtime($leaffilename);
  215. return $ret;
  216. }
  217. function rmMeta($group, $subgroup = null, $leaf = null)
  218. {
  219. $c = & pfcGlobalConfig :: Instance();
  220. $dir = $c->container_cfg_server_dir;
  221. if ($group == NULL)
  222. {
  223. rm_r($dir);
  224. return true;
  225. }
  226. $dir .= '/' . $group;
  227. if ($subgroup == NULL)
  228. {
  229. rm_r($dir);
  230. return true;
  231. }
  232. $dir .= '/' . $subgroup;
  233. if ($leaf == NULL)
  234. {
  235. rm_r($dir);
  236. return true;
  237. }
  238. $leaffilename = $dir . '/' . $leaf;
  239. if (! file_exists($leaffilename))
  240. return false;
  241. unlink($leaffilename);
  242. // check that the directory is empty or not
  243. // remove it if it doesn't contains anything
  244. $dh = opendir($dir);
  245. readdir($dh);
  246. readdir($dh); // skip . and .. directories
  247. $isnotempty = readdir($dh);
  248. closedir($dh);
  249. if ($isnotempty === false)
  250. rmdir($dir);
  251. return true;
  252. }
  253. /**
  254. * Used to encode UTF8 strings to ASCII filenames
  255. */
  256. function encode($str)
  257. {
  258. return urlencode($str);
  259. }
  260. /**
  261. * Used to decode ASCII filenames to UTF8 strings
  262. */
  263. function decode($str)
  264. {
  265. return urldecode($str);
  266. }
  267. }
  268. ?>