PageRenderTime 59ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/php/server/classes/webpage/WebPageManager.php

https://bitbucket.org/sebap/booix
PHP | 463 lines | 268 code | 46 blank | 149 comment | 30 complexity | 0be69e3f0e9f7933c5bceb5bfcd1ac77 MD5 | raw file
  1. <?php
  2. System::import("database/MySQL.php");
  3. System::import("user/User.php");
  4. System::import("webpage/WebPage.php");
  5. System::import("enums/RESPONSE_TYPE.php");
  6. System::import("cpanel/xmlapi.php");
  7. /**
  8. * This class is used to manage the webpages
  9. */
  10. class WebPageManager{
  11. /**
  12. * This is mainly to have all the webpages related to the user
  13. * we cannot use cdata within cdata because it will take the first end delimiter as the delimiter of the first one.
  14. * @param User $user
  15. */
  16. public static function getLightWebPageList($user){
  17. $webPageList;
  18. $db = new MySQL();
  19. $sql="select * from webpages where user_id=".$user->getId();
  20. $result=$db->querySelect($sql);
  21. $cant = $db->getLastQueryCount();
  22. $db->disconnect();
  23. for($i = 0;$i < $cant ;$i++){
  24. $webPage = new WebPage();
  25. $webPage->setId($result[$i]["id"]);
  26. $webPage->setUserId($result[$i]["user_id"]);
  27. $webPage->setSubdomain($result[$i]["subdomain"]);
  28. $webPageList[$i] = $webPage;
  29. }
  30. return $webPageList;
  31. }
  32. public static function store($webPage, $webPageXML, $webPageHTML){
  33. $response = new Response();
  34. $db = new MySQL();
  35. //validate subdomain
  36. //get the current subdomain
  37. $sql="select * from webpages where id=".$webPage->getId()." and user_id=".$webPage->getUserId();
  38. $result=$db->querySelect($sql);
  39. $cant = $db->getLastQueryCount();
  40. $db->disconnect();
  41. if( $cant > 0){
  42. $oldSubdomain = $result[0]["subdomain"];
  43. }else{
  44. $response->setType(RESPONSE_TYPE::$GENERIC_FAILURE);
  45. $response->setMessage("There is no webpage");
  46. return $response;
  47. }
  48. //At this point we know the current subdomain
  49. if($oldSubdomain != $webPage->getSubdomain()){
  50. //validate if the new subdomain is available
  51. $db->connect();
  52. $sql = "select * from webpages where subdomain='".$webPage->getSubdomain()."'";
  53. $result=$db->querySelect($sql);
  54. $cant = $db->getLastQueryCount();
  55. $db->disconnect();
  56. if($cant > 0){
  57. //Here we know the subdomain is not available
  58. $response->setType(RESPONSE_TYPE::$WEBPAGE_STORE_DOMAIN_NOT_AVAILABLE);
  59. return $response;
  60. }else{
  61. //store the new subdomain
  62. $db->connect();
  63. $sql = "update webpages set subdomain='".$webPage->getSubdomain()."' where id=".$webPage->getId()." and user_id=".$webPage->getUserId();
  64. $db->query($sql);
  65. $db->disconnect();
  66. //create subdomain in hostmonster
  67. WebPageManager::createSubdomain($webPage);
  68. if($oldSubdomain != ""){
  69. WebPageManager::deleteSubdomain($oldSubdomain);
  70. }
  71. }
  72. }
  73. //Clean XMLs files
  74. $webPageXML = str_replace("\\","",$webPageXML);
  75. $webPageHTML = str_replace("\\","",$webPageHTML);
  76. $webPageFolderURL = PATH_TO_BOOIX_PAGES."user".$webPage->getUserId()."/page".$webPage->getId() ;
  77. $webPageXMLURL = PATH_TO_BOOIX_PAGES."user".$webPage->getUserId()."/page".$webPage->getId()."/webpage.xml";
  78. $webPageHTMLfolderURL = PATH_TO_BOOIX_PAGES."user".$webPage->getUserId()."/page".$webPage->getId()."/";
  79. //Clean previous files
  80. WebPageManager::deleteAllFiles($webPageFolderURL);
  81. //Now save it
  82. WebPageManager::writeFile($webPageXMLURL, $webPageXML );
  83. $obj = simplexml_load_string($webPageHTML);
  84. $i = 0;
  85. foreach($obj as $element){
  86. if($i == 0){
  87. $content = "<?php header( 'Location: ".$element->name[0]."' ) ; ?>";
  88. WebPageManager::writeFile($webPageHTMLfolderURL."index.php", $content);
  89. }
  90. WebPageManager::writeFile($webPageHTMLfolderURL.$element->name[0], $element->html[0]);
  91. $i++;
  92. }
  93. $response->setType(RESPONSE_TYPE::$WEBPAGE_STORE_STORED);
  94. return $response;
  95. }
  96. /**
  97. *
  98. * @param $webPageId
  99. * @return WebPage object or null if the id does not exists
  100. */
  101. private static function getWebPageFromDB($webPageId){
  102. $db = new MySQL();
  103. $sql = "select * from webpages where id=".$webPageId."";
  104. $result=$db->querySelect($sql);
  105. $cant = $db->getLastQueryCount();
  106. $db->disconnect();
  107. if($cant > 0){
  108. $webPage = new WebPage();
  109. $webPage->setId($result[0]["id"]);
  110. $webPage->setUserId($result[0]["user_id"]);
  111. $webPage->setSubdomain($result[0]["subdomain"]);
  112. //$webPage->setSource(WebPageManager::getWebPageSource($webPage));
  113. return $webPage;
  114. }else{
  115. return null;
  116. }
  117. }
  118. /**
  119. * This method returns the web page xml.
  120. * @param unknown_type $webPage
  121. */
  122. private static function getWebPageSource($webPage){
  123. //A better implementation would be to store the webpage in the database.
  124. $url = PATH_TO_BOOIX_PAGES."/user".$webPage->getUserId()."/page".$webPage->getId()."/webpage.xml";
  125. $webpagexml = file_get_contents($url);
  126. //this is a safety check so we are sure the no process has the handle on this file
  127. for ($i = 0; $i <= 3; $i++) {
  128. if($webpagexml == false ){
  129. //we will sleep 4 seconds and try again
  130. sleep(5);
  131. $webpagexml = file_get_contents($url);
  132. }else{
  133. break;
  134. }
  135. }
  136. return stripslashes($webpagexml);
  137. }
  138. /**
  139. * This method is used to create a new webpage for the user
  140. * @param $webPage
  141. */
  142. public static function delete($webPage){
  143. $response = new Response();
  144. //make sure we get the latest data from DB
  145. $webPage = WebPageManager::getWebPageFromDB($webPage->getId());
  146. if($webPage == null){
  147. $response->setType(RESPONSE_TYPE::$GENERIC_FAILURE);
  148. $response->setMessage("Getting values from db");
  149. return $response;
  150. }
  151. //Delete it from DB
  152. $db = new MySQL();
  153. $sql = "delete from webpages where id=".$webPage->getId();
  154. $db->query($sql);
  155. $err = $db->errorSql();
  156. $db->disconnect();
  157. if($err != 0){
  158. $response->setType(RESPONSE_TYPE::$GENERIC_FAILURE);
  159. $response->setMessage("Error deleting from database". $sql);
  160. return $response;
  161. }
  162. // We will clean up the folder firt
  163. $webPageFolderURL = PATH_TO_BOOIX_PAGES."user".$webPage->getUserId()."/page".$webPage->getId() ;
  164. if(!WebPageManager::recursiveRemoveDirectory($webPageFolderURL)){
  165. $response->setType(RESPONSE_TYPE::$GENERIC_FAILURE);
  166. $response->setMessage("Error deleting the folders");
  167. return $response;
  168. }else{
  169. //delete subdomain, so we can reuse it
  170. //we do not remove it here call it directly independently
  171. //WebPageManager::deleteSubdomain($webPage->getSubdomain());
  172. }
  173. $response->setType(RESPONSE_TYPE::$WEBPAGE_DELETE_DELETED);
  174. $response->setMessage("Success");
  175. $response->setObject($webPage);
  176. return $response;
  177. }
  178. /**
  179. * This method will load a webpage.
  180. * Th
  181. * @param WebPage $webPage
  182. * @return web page xml content. We cannot send a response object because the cdata section issue.
  183. *
  184. */
  185. public static function load($webPage){
  186. //Get the latest webPage Data from DB
  187. $webPage = WebPageManager::getWebPageFromDB($webPage->getId());
  188. //get the webpage xml to return to the client.
  189. $webPageXML = WebPageManager::getWebPageSource($webPage);
  190. echo $webPageXML;
  191. }
  192. /**
  193. * This method is used to create a new webpage for the user
  194. * @param $webPage
  195. */
  196. public static function create($webPage){
  197. $response = new Response();
  198. $db = new MySQL();
  199. //validate if the new subdomain is available
  200. $sql = "select * from webpages where subdomain='".$webPage->getSubdomain()."'";
  201. $result=$db->querySelect($sql);
  202. $cant = $db->getLastQueryCount();
  203. $db->disconnect();
  204. if( $cant > 0){
  205. //Here we know the subdomain is not available
  206. $response->setType(RESPONSE_TYPE::$WEBPAGE_STORE_DOMAIN_NOT_AVAILABLE);
  207. $response->setMessage("Domain is not available");
  208. return $response;
  209. }else{
  210. //this will update the id too
  211. $webPage = WebPageManager::createWebPage($webPage);
  212. //WebPageManager::createSubdomain($webPage);
  213. }
  214. $response->setType(RESPONSE_TYPE::$WEBPAGE_STORE_STORED);
  215. $response->setMessage("Page Stored Sucessfully");
  216. $response->setObject($webPage);
  217. return $response;
  218. }
  219. /**
  220. * Used to create a new page
  221. * @param $userId
  222. * @param $subdomain
  223. * @return newly created page id
  224. */
  225. public static function createWebPage($webPage){
  226. $sql="insert into webpages (user_id, subdomain) values (".$webPage->getUserId().", '".$webPage->getSubdomain()."')";
  227. $db = new MySQL();
  228. $db->query($sql);
  229. $webPage->setId($db->insert_id());
  230. $db->disconnect();
  231. WebPageManager::recurseCopy(PATH_TO_BOOIX_PAGES."default_page/", PATH_TO_BOOIX_PAGES."user".$webPage->getUserId()."/page". $webPage->getId() );
  232. $webPageXML = WebPageManager::getWebPageSource($webPage);
  233. $webPageXML = str_replace("#webPageId#", $webPage->getId() , $webPageXML);
  234. $webPageXML = str_replace("#subdomain#", $webPage->getSubdomain() , $webPageXML);
  235. $webPageXMLURL = PATH_TO_BOOIX_PAGES."user".$webPage->getUserId()."/page".$webPage->getId()."/webpage.xml";
  236. WebPageManager::writeFile($webPageXMLURL, $webPageXML );
  237. return $webPage;
  238. }
  239. private static function recurseCopy($src,$dst) {
  240. $dir = opendir($src);
  241. @mkdir($dst);
  242. while(false !== ( $file = readdir($dir)) ) {
  243. if (( $file != '.' ) && ( $file != '..' )) {
  244. if ( is_dir($src . '/' . $file) ) {
  245. WebPageManager::recurseCopy($src . '/' . $file,$dst . '/' . $file);
  246. }
  247. else {
  248. copy($src . '/' . $file,$dst . '/' . $file);
  249. }
  250. }
  251. }
  252. closedir($dir);
  253. }
  254. /**
  255. * This method will delete only the files find in a specified directory
  256. * @param path to a dir $dir
  257. */
  258. private static function deleteAllFiles($dir) {
  259. $mydir = opendir($dir);
  260. while(false !== ($file = readdir($mydir))) {
  261. if($file != "." && $file != "..") {
  262. chmod($dir."/".$file, 0777);
  263. if(is_dir($dir."/".$file)) {
  264. //We are not deleting folders here sir.
  265. /*chdir('.');
  266. destroy($dir.$file.'/');
  267. rmdir($dir.$file) or DIE("couldn't delete $dir$file<br />");*/
  268. }
  269. else{
  270. unlink($dir."/".$file) or DIE("couldn't delete $dir$file<br />");
  271. }
  272. }
  273. }
  274. closedir($mydir);
  275. }
  276. /*
  277. * this method will delete the whole directory and its content
  278. */
  279. public static function recursiveRemoveDirectory($directory, $empty=FALSE){
  280. if(substr($directory,-1) == '/')
  281. {
  282. $directory = substr($directory,0,-1);
  283. }
  284. if(!file_exists($directory) || !is_dir($directory))
  285. {
  286. return FALSE;
  287. }elseif(is_readable($directory))
  288. {
  289. $handle = opendir($directory);
  290. while (FALSE !== ($item = readdir($handle)))
  291. {
  292. if($item != '.' && $item != '..')
  293. {
  294. $path = $directory.'/'.$item;
  295. if(is_dir($path))
  296. {
  297. WebPageManager::recursiveRemoveDirectory($path);
  298. }else{
  299. unlink($path);
  300. }
  301. }
  302. }
  303. closedir($handle);
  304. if($empty == FALSE)
  305. {
  306. if(!rmdir($directory))
  307. {
  308. return FALSE;
  309. }
  310. }
  311. }
  312. return TRUE;
  313. }
  314. private static function writeFile($filename , $content){
  315. $fh = fopen($filename, 'w') or die("can't open file");
  316. fwrite($fh, $content);
  317. fwrite($fh, $stringData);
  318. fclose($fh);
  319. }
  320. /**
  321. * This method has given me nightmares. it seems that the process of creating a subdomain, creates
  322. * many resources. This process can take long time, so if the user tries to access the webpage that is in the same
  323. * fodler can lead to errors.
  324. * This can be fixed by storing the web page in the database, not in the filesystem.
  325. *
  326. * One of the problems we have with this method is that the execution of this creation of the subdomain, returns an error.
  327. * I could not figure out what was the issue, but it actually creates the subdomain. I think Hostmonster is not quite ready for this
  328. * but as a work around, we will trust it will work everytime, and we will ignore the response from this method.
  329. *
  330. * @param WebPage $webPage
  331. */
  332. public static function createSubdomain($webPage){
  333. /*$dir = PATH_TO_BOOIX_PAGES."user".$webPage->getUserId()."/page".$webPage->getId() ;
  334. $dir = "public_html/booix/webpages/user".$webPage->getUserId()."/page".$webPage->getId() ;
  335. $url = "http://".CPANEL_USER.":".CPANEL_PASS."@".CPANEL_DOMAIN.":2082/frontend/".CPANEL_SKIN."/subdomain/doadddomain.html?";
  336. $url = $url . "domain=".$webPage->getSubdomain()."&rootdomain=".CPANEL_DOMAIN."&dir=".$dir."&go=Create";*/
  337. /*$xmlapi = new xmlapi(CPANEL_DOMAIN);
  338. $xmlapi->set_port(2082);
  339. $xmlapi->password_auth(CPANEL_USER,CPANEL_PASS);
  340. //Check if fork exists
  341. if ( function_exists('pcntl_fork') ){
  342. $pid = pcntl_fork();
  343. if($pid) { //parent
  344. //we do not want the next line because it causes the process to fail
  345. //pcntl_wait($status);
  346. }else { //child
  347. $xmlapi->api1_query(CPANEL_USER,'SubDomain','addsubdomain',array($webPage->getSubdomain(),CPANEL_DOMAIN,0,0,"public_html/booix/webpages/user".$webPage->getUserId()."/page".$webPage->getId()));
  348. exit(0);
  349. }
  350. }else{
  351. $result = $xmlapi->api1_query(CPANEL_USER,'SubDomain','addsubdomain',array($webPage->getSubdomain(),CPANEL_DOMAIN,0,0,"public_html/booix/webpages/user".$webPage->getUserId()."/page".$webPage->getId()));
  352. }*/
  353. //$result = $xmlapi->api1_query(CPANEL_USER,'SubDomain','addsubdomain',array($webPage->getSubdomain(),CPANEL_DOMAIN,0,0,"public_html/booix/webpages/user".$webPage->getUserId()."/page".$webPage->getId()));
  354. /**
  355. * @link http://docs.cpanel.net/twiki/bin/view/ApiDocs/WebHome
  356. */
  357. //Creating a subdomain via xml api
  358. $xmlapi = new xmlapi(CPANEL_DOMAIN);
  359. $xmlapi->set_port(2082);
  360. $xmlapi->password_auth(CPANEL_USER,CPANEL_PASS);
  361. $result = $xmlapi->api1_query(CPANEL_USER,'SubDomain','addsubdomain',array($webPage->getSubdomain(),CPANEL_DOMAIN,0,0,"public_html/booix/webpages/user".$webPage->getUserId()."/page".$webPage->getId()));
  362. print_r ($result);
  363. return $result;
  364. }
  365. /**
  366. * This method is used to delete a subdomain from hostmonster.
  367. * This method can be moved to the SubdomainManager class. but for time constraint we leave it here.
  368. * @param String $subdomain
  369. */
  370. public static function deleteSubdomain($subdomain){
  371. $url = "http://".CPANEL_USER.":".CPANEL_PASS."@".CPANEL_DOMAIN.":2082/frontend/".CPANEL_SKIN."/subdomain/dodeldomain.html?";
  372. $url = $url . "domain=".$subdomain."_".CPANEL_DOMAIN;
  373. $result = file_get_contents($url);
  374. print_r ($result);
  375. return $result;
  376. /*
  377. * This portion of code is kept in kere justa s a reference and for informational purposes.
  378. * we already tried to fork the process in the server but didnt work, so
  379. * the best alternative is to wait for the response from hostmonster, eventhought it is not a clean response
  380. * we can ignore ir
  381. *
  382. if ( function_exists('pcntl_fork') ){
  383. $pid = pcntl_fork();
  384. if($pid) { //parent
  385. //we do not want the next line because it causes the process to fail
  386. //pcntl_wait($status);
  387. }else { //child
  388. $result = file_get_contents($url);
  389. if ($result === false)
  390. {
  391. //retry
  392. $result = file_get_contents($url);
  393. } else {
  394. exit(0);
  395. }
  396. }
  397. }else{
  398. file_get_contents($url);
  399. }*/
  400. /**
  401. * @link http://docs.cpanel.net/twiki/bin/view/ApiDocs/WebHome
  402. * This also did not work
  403. */
  404. //Deleting a subdomain via xml api
  405. /*$xmlapi = new xmlapi(CPANEL_DOMAIN,CPANEL_USER,CPANEL_PASS);
  406. $xmlapi->set_port(2083);
  407. $result = $xmlapi->api2_query(CPANEL_USER,'SubDomain','delsubdomain',array($subdomain."_".CPANEL_DOMAIN));
  408. print_r ($result);
  409. return $result;*/
  410. }
  411. }
  412. ?>