PageRenderTime 52ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/core/core.php

https://bitbucket.org/navigatecms/navigatecms
PHP | 1149 lines | 725 code | 153 blank | 271 comment | 126 complexity | 975f8b2a716e3c356604418db8fddbb2 MD5 | raw file
Possible License(s): GPL-2.0, MIT, LGPL-2.1, BSD-3-Clause, AGPL-3.0, Apache-2.0
  1. <?php
  2. /**
  3. *
  4. * Navigate CMS common core functions
  5. *
  6. * @copyright Copyright (C) 2010-2013 Naviwebs. All rights reserved.
  7. * @author Naviwebs (http://www.naviwebs.com/)
  8. * @license http://www.gnu.org/licenses/gpl-2.0.html GPLv2 License
  9. * @version 1.7.7 2013-09-07
  10. *
  11. */
  12. /**
  13. * Returns the translated version of an internal CMS string
  14. *
  15. * Given a certain ID, function t returns the associated string
  16. * in the current active language.
  17. *
  18. * @param integer $id The ID of the string on Navigate CMS dictionary
  19. * @param string $default The default string to be returned if no translation found
  20. * @param array $replace Array of substitutions; example: "Your name is {your_name}" [ 'your_name' => 'Navigate' ]
  21. * @param boolean $encodeChars Encode some special characters as HTML entities
  22. * @return string
  23. */
  24. function t($id, $default='', $replace=array(), $encodeChars=false)
  25. {
  26. global $lang;
  27. global $session;
  28. if(!method_exists($lang, 't'))
  29. {
  30. $lang = new language();
  31. $lang->load($session['lang']);
  32. }
  33. $out = $lang->t($id, $default, $replace, $encodeChars);
  34. if(empty($out))
  35. $out = $default;
  36. return $out;
  37. }
  38. /**
  39. * Protects a string before inserting it into the database
  40. *
  41. * @param string $text
  42. * @param string $wrapped_by Surround the input string with "double" or 'single' quotes (default is "double")
  43. * @return string
  44. */
  45. function protect($text, $wrapped_by="", $keep_numeric=false)
  46. {
  47. global $DB;
  48. if($keep_numeric && is_numeric($text))
  49. return $text;
  50. return $DB->protect($text, $wrapped_by);
  51. }
  52. /**
  53. * Encodes " character to &quot; (HTML char)
  54. *
  55. * @param string $text
  56. * @return string
  57. */
  58. function pquotes($text)
  59. {
  60. return str_replace('"', '&quot;', $text);
  61. }
  62. /**
  63. * Executes a Navigate CMS function taking the 'fid' url parameter
  64. * fid can be the name of the package (p.e. "dashboard") or its numeric assignment (p.e. "6")
  65. * note: if no "fid" is found, then loads the first available menu function
  66. *
  67. * @return mixed Navigate CMS package output
  68. */
  69. function core_run()
  70. {
  71. global $layout;
  72. global $menu_layout;
  73. $content = "";
  74. $fid = 'dashboard'; // default function
  75. if(isset($_REQUEST['fid']))
  76. $fid = $_REQUEST['fid'];
  77. $f = core_load_function($fid);
  78. if(empty($f) && ($fid=="dashboard" || empty($fid)))
  79. {
  80. // load first function available
  81. $fid = $menu_layout->menus[0]->items[0]->codename;
  82. if(empty($fid))
  83. $fid = "unknown";
  84. else
  85. {
  86. header('location: '.NAVIGATE_MAIN.'?fid='.$fid);
  87. core_terminate();
  88. }
  89. }
  90. if(file_exists('lib/packages/'.$f->codename.'/'.$f->codename.'.php'))
  91. {
  92. include('lib/packages/'.$f->codename.'/'.$f->codename.'.php');
  93. $content = run();
  94. }
  95. else
  96. $content = 'function '.$fid.': <strong>'.$f->codename.'</strong> has not been found!';
  97. return $content;
  98. }
  99. /**
  100. * Finish Navigate CMS execution sending a flush, writing the session and disconnecting the database
  101. *
  102. */
  103. function core_terminate()
  104. {
  105. global $DB;
  106. flush();
  107. session_write_close();
  108. if($DB)
  109. $DB->disconnect();
  110. exit;
  111. }
  112. /**
  113. * Loads the metadata of a function giving its name or numeric code
  114. *
  115. * @param mixed $fid
  116. * @return object $function
  117. */
  118. function core_load_function($fid)
  119. {
  120. global $DB;
  121. global $menu_layout;
  122. // check if fid is an internal function
  123. // or we need to retrieve its information from the database
  124. switch($fid)
  125. {
  126. case 'grid_notes':
  127. $func = new stdClass();
  128. $func->id = 'grid_notes';
  129. $func->codename = 'grid_notes';
  130. $func->category = 'content';
  131. $func->icon = '';
  132. $func->lid = '';
  133. $func->enabled = 1;
  134. break;
  135. case 'permissions':
  136. $func = new stdClass();
  137. $func->id = 'permissions';
  138. $func->codename = 'permissions';
  139. $func->category = 'config';
  140. $func->icon = '';
  141. $func->lid = '';
  142. $func->enabled = 1;
  143. break;
  144. default:
  145. if(is_numeric($fid))
  146. $where = 'id = '.intval($fid);
  147. else
  148. $where = 'codename = '.protect($fid);
  149. $DB->query('SELECT *
  150. FROM nv_functions
  151. WHERE '.$where.'
  152. AND enabled = 1');
  153. $func = $DB->first();
  154. if(!$menu_layout->function_is_displayed($func->id))
  155. $func = false;
  156. }
  157. return $func;
  158. }
  159. /**
  160. * Converts a user formatted date to a unix timestamp
  161. *
  162. * @param string $date
  163. * @return integer
  164. */
  165. function core_date2ts($date)
  166. {
  167. global $user;
  168. global $website;
  169. $ts = 0;
  170. $aDate = explode(" ", $date); // hour is always the last part
  171. $aDate = array_values(array_filter($aDate));
  172. list($date, $time) = $aDate;
  173. if(!empty($time))
  174. list($hour, $minute) = explode(":", $time);
  175. else
  176. {
  177. $hour = 0;
  178. $minute = 0;
  179. }
  180. if(empty($user->timezone))
  181. $user->timezone = 'UTC';
  182. switch($user->date_format)
  183. {
  184. case "Y-m-d H:i":
  185. list($year, $month, $day) = explode("-", $date);
  186. break;
  187. case "d-m-Y H:i":
  188. list($day, $month, $year) = explode("-", $date);
  189. break;
  190. case "m-d-Y H:i":
  191. list($month, $day, $year) = explode("-", $date);
  192. break;
  193. case "Y/m/d H:i":
  194. list($year, $month, $day) = explode("/", $date);
  195. break;
  196. case "d/m/Y H:i":
  197. list($day, $month, $year) = explode("/", $date);
  198. break;
  199. case "m/d/Y H:i":
  200. list($month, $day, $year) = explode("/", $date);
  201. break;
  202. }
  203. // works on PHP 5.2+
  204. $userTimezone = new DateTimeZone($user->timezone);
  205. $utcTimezone = new DateTimeZone('UTC');
  206. $date = new DateTime($year.'-'.$month.'-'.$day.' '.$hour.':'.$minute, $userTimezone);
  207. $offset = $utcTimezone->getOffset($date);
  208. $ts = $date->format('U') + $offset;
  209. return $ts;
  210. }
  211. /**
  212. * Converts a UNIX timestamp to a user formatted date
  213. *
  214. * @param integer $timestamp
  215. * @param boolean $time Set true to add the time after the date
  216. * @return string
  217. */
  218. function core_ts2date($timestamp, $time=false)
  219. {
  220. global $user;
  221. $format = $user->date_format;
  222. if(empty($format))
  223. $format = "Y-m-d H:i";
  224. if(!$time) $format = str_replace('H:i', '', $format);
  225. $user_timezone = 'UTC';
  226. if(!empty($user->timezone))
  227. $user_timezone = $user->timezone;
  228. $date = new DateTime();
  229. if(version_compare(PHP_VERSION, '5.3.0') < 0)
  230. {
  231. $datets = getdate( ( int ) $timestamp );
  232. $date->setDate( $datets['year'] , $datets['mon'] , $datets['mday'] );
  233. $date->setTime( $datets['hours'] , $datets['minutes'] , $datets['seconds'] );
  234. }
  235. else
  236. {
  237. $date->setTimestamp(intval($timestamp));
  238. $date->setTimezone(new DateTimeZone($user_timezone));
  239. }
  240. return $date->format($format);
  241. }
  242. function core_ts2elapsed_time($timestamp)
  243. {
  244. $time_elapsed = time() - $timestamp;
  245. $seconds = $time_elapsed ;
  246. $minutes = round($time_elapsed / 60 );
  247. $hours = round($time_elapsed / 3600);
  248. $days = round($time_elapsed / 86400 );
  249. $weeks = round($time_elapsed / 604800);
  250. $months = round($time_elapsed / 2600640 );
  251. $years = round($time_elapsed / 31207680 );
  252. // Seconds
  253. if($seconds <= 60)
  254. {
  255. $out = t(564, "%s seconds ago", array('%s' => $seconds));
  256. }
  257. //Minutes
  258. else if($minutes <= 60)
  259. {
  260. if($minutes==1)
  261. $out = t(565, "one minute ago");
  262. else
  263. $out = t(566, "%m minutes ago", array('%m' => $minutes));
  264. }
  265. //Hours
  266. else if($hours <=24)
  267. {
  268. if($hours==1)
  269. $out = t(567, "an hour ago");
  270. else
  271. $out = t(568, "%h hours ago", array('%h' => $hours));
  272. }
  273. //Days
  274. else if($days <= 7)
  275. {
  276. if($days==1)
  277. $out = t(569, "yesterday");
  278. else
  279. $out = t(570, "%d days ago", array('%d' => $days));
  280. }
  281. //Weeks
  282. else if($weeks <= 4.3)
  283. {
  284. if($weeks==1)
  285. $out = t(571, "a week ago");
  286. else
  287. $out = t(572, "%w weeks ago", array('%w' => $weeks));
  288. }
  289. //Months
  290. else if($months <=12)
  291. {
  292. if($months==1)
  293. $out = t(573, "a month ago");
  294. else
  295. $out = t(574, "%m months ago", array('%m' => $months));
  296. }
  297. //Years
  298. else
  299. {
  300. if($years==1)
  301. $out = t(575, "one year ago");
  302. else
  303. $out = t(576, "%y years ago", array('%y' => $years));
  304. }
  305. return $out;
  306. }
  307. /**
  308. * Returns the current UNIX timestamp (UTC)
  309. *
  310. * @return integer
  311. */
  312. function core_time()
  313. {
  314. if(class_exists("DateTime"))
  315. {
  316. $ts = new DateTime();
  317. return $ts->format("U");
  318. }
  319. else
  320. return time();
  321. }
  322. /**
  323. * Converts numeric value from string to its decimal representation
  324. * the format depends on the current signed in user and his preferences (decimal_separator, thousands_separator)
  325. *
  326. * @param string $value
  327. * @return string internal PHP representation of a decimal number (dot notation)
  328. */
  329. function core_string2decimal($value)
  330. {
  331. global $user;
  332. if(empty($user) || !isset($user->decimal_separator))
  333. {
  334. $user = new user();
  335. $user->decimal_separator = 'Âż'; // if no user preference, set a random character to represent the decimal separator
  336. }
  337. // remove all characters except numbers, the negative symbol and the decimal character (defined by the current user)
  338. $value = preg_replace('/[^0-9\/-\/'.$user->decimal_separator.']/', '', $value);
  339. // replace the user decimal character for the internal PHP symbol: a dot .
  340. $value = str_replace($user->decimal_separator, ".", $value);
  341. return $value;
  342. }
  343. /**
  344. * Sends an e-mail using the account details entered in the website settings form
  345. * Note: if this function is called when the url has the parameter "debug", a log of the process is dumped
  346. *
  347. * @param string $subject
  348. * @param string $body
  349. * @param mixed $recipients An e-mail address string or an array of recipients [name => address, name => ...]
  350. * @param array $attachments Files or data to be attached. [0][file => "/path/to/file", name => "name_of_the_file_in_the_email"]... [1][data => "binary data", name => "name_of_the_file_in_the_email"]
  351. * @param boolean $quiet hide any possible exception message
  352. * @return boolean True if the mail has been sent, false otherwise
  353. *
  354. */
  355. function navigate_send_email($subject, $body, $recipients=array(), $attachments=array(), $quiet=false)
  356. {
  357. global $website;
  358. $mail = new PHPMailer(true); // the true param means it will throw exceptions on errors, which we need to catch
  359. $mail->CharSet = 'UTF-8';
  360. if($website->mail_mailer=='sendmail')
  361. $mail->IsSendmail(); // telling the class to use Sendmail
  362. else if($website->mail_mailer=='mail')
  363. $mail->IsMail(); // telling the class to use PHP Mail
  364. else
  365. $mail->IsSMTP(); // telling the class to use SMTP
  366. try
  367. {
  368. $mail->Host = $website->mail_server;
  369. $mail->SMTPAuth = true;
  370. $mail->Port = $website->mail_port;
  371. if($website->mail_security=='1') // SSL/TLS
  372. $mail->SMTPSecure = "ssl";
  373. if($website->mail_security=='2') // STARTTLS
  374. {
  375. $mail->SMTPSecure = "tls";
  376. }
  377. if($website->mail_ignore_ssl_security)
  378. {
  379. // some servers have incorrect security settings, missing certificates, etc.
  380. $mail->SMTPOptions = array(
  381. 'ssl' => array(
  382. 'verify_peer' => false,
  383. 'verify_peer_name' => false,
  384. 'allow_self_signed' => true
  385. )
  386. );
  387. }
  388. $mail->Username = $website->mail_user;
  389. $mail->Password = $website->mail_password;
  390. if(APP_DEBUG)
  391. $mail->SMTPDebug = 1;
  392. if(empty($recipients))
  393. {
  394. // if no recipients given, assign the website contacts
  395. $recipients = $website->contact_emails;
  396. }
  397. if(!is_array($recipients)) // single recipient or several emails (multiline)
  398. {
  399. if(strpos($recipients, "\n")!=false)
  400. $recipients = explode("\n", $recipients);
  401. else
  402. $recipients = array($recipients);
  403. }
  404. $from_email_address = $website->mail_address;
  405. if(empty($from_email_address))
  406. $from_email_address = 'no-reply@website.com';
  407. $mail->SetFrom($from_email_address, $website->name);
  408. $mail->IsHTML(true);
  409. $mail->Subject = $subject;
  410. $mail->MsgHTML($body);
  411. $mail->AltBody = strip_tags($body);
  412. if(is_array($attachments))
  413. {
  414. for($i=0; $i< count($attachments); $i++)
  415. {
  416. if(!empty($attachments[$i]['file']))
  417. {
  418. $mail->AddAttachment($attachments[$i]['file'], $attachments[$i]['name']);
  419. }
  420. else
  421. {
  422. $mail->AddStringAttachment($attachments[$i]['data'], $attachments[$i]['name']);
  423. }
  424. }
  425. }
  426. $already_sent = array();
  427. foreach($recipients as $name => $email)
  428. {
  429. // avoid sending someone the same email two times
  430. if(in_array($email, $already_sent))
  431. continue;
  432. if(empty($email) && !empty($name))
  433. $email = $name;
  434. $mail->ClearAddresses();
  435. $mail->AddAddress($email, $name);
  436. $mail->Send();
  437. array_push($already_sent, $email);
  438. }
  439. $ok = true; // no exceptions => mail sent
  440. }
  441. catch (phpmailerException $e)
  442. {
  443. if(!$quiet)
  444. echo $e->errorMessage(); //Pretty error messages from PHPMailer
  445. $ok = false;
  446. }
  447. catch (Exception $e)
  448. {
  449. if(!$quiet)
  450. echo $e->getMessage(); //Boring error messages from anything else!
  451. $ok = false;
  452. }
  453. return $ok;
  454. }
  455. /**
  456. * Checks if a string is not empty after a trim
  457. *
  458. * @param string $text
  459. * @return boolean
  460. */
  461. function is_not_empty($text)
  462. {
  463. $text = trim($text);
  464. return !empty($text);
  465. }
  466. /**
  467. * Cleans a string of: tags, new lines and duplicated spaces
  468. *
  469. * @param string $text
  470. * @return string
  471. */
  472. function core_string_clean($text="")
  473. {
  474. $text = strip_tags($text);
  475. $text = str_replace("\n", " ", $text);
  476. $text = str_replace("\r", " ", $text);
  477. $text = preg_replace('/(\s+)/', " ", $text);
  478. return $text;
  479. }
  480. /**
  481. * Cleans a string of any nv tags: <nv /> or {{nv}}
  482. *
  483. * @param string $text
  484. * @return string
  485. */
  486. function core_remove_nvtags($text)
  487. {
  488. $text = preg_replace("/<nv[^>]+\>/i", "", $text);
  489. $text = preg_replace("/{{nv[^>]+}}/i", "", $text);
  490. return $text;
  491. }
  492. /**
  493. * Cuts a text string to a certain length; any HTML tag is removed and text is cutted without breaking words
  494. *
  495. * @param string $text
  496. * @param string $maxlen Maximum character length
  497. * @param string $morechar Append string if the original text is cutted somewhere
  498. * @param array $allowedtags List of tags which have to be kept (for example 'a')
  499. * @return string
  500. */
  501. function core_string_cut($text, $maxlen, $morechar='&hellip;', $allowedtags=array())
  502. {
  503. if(!empty($allowedtags))
  504. {
  505. if(!is_array($allowedtags))
  506. $allowedtags = array($allowedtags);
  507. $text = strip_tags($text, '<'.implode('><', $allowedtags).'>');
  508. $text = core_truncate_html($text, $maxlen, $morechar);
  509. }
  510. else
  511. {
  512. // truncate by plain text
  513. $text = strip_tags($text);
  514. $text = html_entity_decode($text, ENT_QUOTES, 'UTF-8');
  515. $olen = strlen($text);
  516. if($olen < $maxlen) return $text;
  517. $pos = strrpos( substr( $text , 0 , $maxlen), ' ') ;
  518. $text = substr( $text , 0 , $pos );
  519. if($olen > $maxlen) $text.= $morechar;
  520. }
  521. return $text;
  522. }
  523. /**
  524. * function to truncate and then clean up end of the HTML,
  525. * truncates by counting characters outside of HTML tags
  526. *
  527. * @author Alex Lockwood, alex dot lockwood at websightdesign
  528. * @updated by Marc Lobato [try not to truncate words]
  529. *
  530. * @param string $str the string to truncate
  531. * @param int $len the number of characters
  532. * @param string $end the end string for truncation
  533. * @return string $truncated_html
  534. *
  535. * **/
  536. function core_truncate_html($str, $len, $end = '&hellip;')
  537. {
  538. $closeTagString = '';
  539. //find all tags
  540. $tagPattern = '/(<\/?)([\w]*)(\s*[^>]*)>?|&[\w#]+;/i'; //match html tags and entities
  541. preg_match_all($tagPattern, $str, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER );
  542. $i =0;
  543. //loop through each found tag that is within the $len, add those characters to the len,
  544. //also track open and closed tags
  545. // $matches[$i][0] = the whole tag string --the only applicable field for html enitities
  546. // IF its not matching an &htmlentity; the following apply
  547. // $matches[$i][1] = the start of the tag either '<' or '</'
  548. // $matches[$i][2] = the tag name
  549. // $matches[$i][3] = the end of the tag
  550. //$matces[$i][$j][0] = the string
  551. //$matces[$i][$j][1] = the str offest
  552. while($matches[$i][0][1] < $len && !empty($matches[$i]))
  553. {
  554. $len = $len + strlen($matches[$i][0][0]);
  555. if(substr($matches[$i][0][0],0,1) == '&' )
  556. $len = $len-1;
  557. //if $matches[$i][2] is undefined then its an html entity, want to ignore those for tag counting
  558. //ignore empty/singleton tags for tag counting
  559. if(!empty($matches[$i][2][0]) && !in_array($matches[$i][2][0],array('br','img','hr', 'input', 'param', 'link')))
  560. {
  561. //double check
  562. if(substr($matches[$i][3][0],-1) !='/' && substr($matches[$i][1][0],-1) !='/')
  563. $openTags[] = $matches[$i][2][0];
  564. elseif(end($openTags) == $matches[$i][2][0])
  565. array_pop($openTags);
  566. else
  567. $warnings[] = "html has some tags mismatched in it: $str";
  568. }
  569. $i++;
  570. }
  571. $closeTags = '';
  572. if (!empty($openTags))
  573. {
  574. $openTags = array_reverse($openTags);
  575. foreach ($openTags as $t)
  576. {
  577. $closeTagString .="</".$t . ">";
  578. }
  579. }
  580. if(strlen($str) > $len)
  581. {
  582. // look for the first space character after the required length
  583. // then, truncate with new len
  584. $slen = core_strpos_array($str, array(' ', ',', '.', ';', "\n"), $len);
  585. if(!$slen)
  586. $truncated_html = substr($str, 0, $len);
  587. else
  588. $truncated_html = substr($str, 0, $slen);
  589. //add the end text
  590. $truncated_html .= $end ;
  591. //restore any open tags
  592. $truncated_html .= $closeTagString;
  593. }
  594. else
  595. $truncated_html = $str;
  596. return $truncated_html;
  597. }
  598. function core_strpos_array($haystack, $needles, $offset)
  599. {
  600. if ( is_array($needles) )
  601. {
  602. foreach ($needles as $str)
  603. {
  604. if ( is_array($str) )
  605. {
  606. $pos = core_strpos_array($haystack, $str, $offset);
  607. }
  608. else
  609. {
  610. $pos = strpos($haystack, $str, $offset);
  611. }
  612. if ($pos !== FALSE)
  613. return $pos;
  614. }
  615. }
  616. else
  617. {
  618. return strpos($haystack, $needles, $offset);
  619. }
  620. }
  621. /**
  622. * Translate a number of bytes to a human readable format (from Bytes to PetaBytes)
  623. *
  624. * @param integer $bytes
  625. * @return string
  626. */
  627. function core_bytes($bytes)
  628. {
  629. $unim = array("Bytes", "KB", "MB", "GB", "TB", "PB");
  630. $c = 0;
  631. while ($bytes >= 1024)
  632. {
  633. $c++;
  634. $bytes = $bytes / 1024;
  635. }
  636. return number_format($bytes, ($c ? 2 : 0),",",".")." ".$unim[$c];
  637. }
  638. /**
  639. * Executes a simple GET HTTP request using CURL if available, file_get_contents otherwise
  640. *
  641. * @param string $url
  642. * @param integer $timeout
  643. * @return string Body of the response
  644. */
  645. function core_http_request($url, $timeout=8)
  646. {
  647. if(function_exists('curl_init'))
  648. {
  649. $ch = curl_init();
  650. curl_setopt($ch, CURLOPT_HEADER, 0);
  651. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  652. curl_setopt($ch, CURLOPT_URL, $url);
  653. curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
  654. $data = curl_exec($ch);
  655. curl_close($ch);
  656. }
  657. else
  658. {
  659. $data = file_get_contents($url);
  660. }
  661. return $data;
  662. }
  663. /**
  664. * Execute a CURL HTTP POST request with parameters
  665. * Author: Mahesh Chari
  666. * Website: http://www.maheshchari.com/simple-curl-function-to-send-data-remote-server/
  667. *
  668. * @param string $url
  669. * @param mixed $postdata Array of parameter => value or POST string
  670. * @param string $header HTTP header
  671. * @param mixed $timeout Number of seconds to wait for a HTTP response
  672. * @return string Body of the response
  673. */
  674. function core_curl_post($url, $postdata = NULL, $header = NULL, $timeout = 60, $method="post")
  675. {
  676. $s = curl_init();
  677. // initialize curl handler
  678. curl_setopt($s, CURLOPT_URL, $url);
  679. //set option URL of the location
  680. if ($header)
  681. curl_setopt($s, CURLOPT_HTTPHEADER, $header);
  682. //set headers if presents
  683. curl_setopt($s, CURLOPT_TIMEOUT, $timeout);
  684. //time out of the curl handler
  685. curl_setopt($s, CURLOPT_CONNECTTIMEOUT, $timeout);
  686. //time out of the curl socket connection closing
  687. curl_setopt($s, CURLOPT_MAXREDIRS, 3);
  688. //set maximum URL redirections to 3
  689. curl_setopt($s, CURLOPT_RETURNTRANSFER, true);
  690. // set option curl to return as string, don't output directly
  691. // on some configurations: CURLOPT_FOLLOWLOCATION cannot be activated when safe_mode is enabled or an open_basedir is set
  692. @curl_setopt($s, CURLOPT_FOLLOWLOCATION, true);
  693. curl_setopt($s, CURLOPT_COOKIEJAR, 'cache/cookie.curl.txt');
  694. curl_setopt($s, CURLOPT_COOKIEFILE, 'cache/cookie.curl.txt');
  695. //set a cookie text file, make sure it is writable chmod 777 permission to cookie.txt
  696. if(strtolower($method) == 'post')
  697. {
  698. curl_setopt($s,CURLOPT_POST, true);
  699. //set curl option to post method
  700. curl_setopt($s,CURLOPT_POSTFIELDS, $postdata); // can be a string or an associative array
  701. //if post data present send them.
  702. }
  703. else if(strtolower($method) == 'delete')
  704. {
  705. curl_setopt($s,CURLOPT_CUSTOMREQUEST, 'DELETE');
  706. //file transfer time delete
  707. }
  708. else if(strtolower($method) == 'put')
  709. {
  710. curl_setopt($s,CURLOPT_CUSTOMREQUEST, 'PUT');
  711. curl_setopt($s,CURLOPT_POSTFIELDS, $postdata);
  712. //file transfer to post ,put method and set data
  713. }
  714. curl_setopt($s,CURLOPT_HEADER, 0);
  715. // curl send header
  716. curl_setopt($s,CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1');
  717. //proxy as Mozilla browser
  718. curl_setopt($s, CURLOPT_SSL_VERIFYPEER, false);
  719. // don't need to SSL verify ,if present it need openSSL PHP extension
  720. $html = curl_exec($s);
  721. //run handler
  722. $status = curl_getinfo($s, CURLINFO_HTTP_CODE);
  723. // get the response status
  724. curl_close($s);
  725. //close handler
  726. @unlink('cache/cookie.curl.txt');
  727. return $html;
  728. //return output
  729. }
  730. /**
  731. * Retrieves the size of a remote file doing a CURL request
  732. *
  733. * @param string $file URL of the file
  734. * @return integer|boolean Size of the file in bytes or false
  735. */
  736. function core_filesize_curl($file)
  737. {
  738. $ch = curl_init($file);
  739. curl_setopt($ch, CURLOPT_NOBODY, true);
  740. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  741. curl_setopt($ch, CURLOPT_HEADER, true);
  742. // on some configurations: CURLOPT_FOLLOWLOCATION cannot be activated when safe_mode is enabled or an open_basedir is set
  743. @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  744. $data = curl_exec($ch);
  745. curl_close($ch);
  746. if ($data === false)
  747. return false;
  748. if (preg_match('/Content-Length: (\d+)/', $data, $matches))
  749. return (float)$matches[1];
  750. }
  751. /**
  752. * Retrieves a remote file doing a CURL request
  753. *
  754. * @param string $url URL of the file
  755. * @param string $file Absolute system path where the file will be saved
  756. * @return string $contents File contents
  757. */
  758. function core_file_curl($url, $file)
  759. {
  760. // prepare URL
  761. $userAgent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)';
  762. $ch = curl_init($url);
  763. curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
  764. curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, false);
  765. curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
  766. curl_setopt($ch, CURLOPT_NOBODY, true);
  767. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  768. curl_setopt($ch, CURLOPT_HEADER, true);
  769. // on some configurations: CURLOPT_FOLLOWLOCATION cannot be activated when safe_mode is enabled or an open_basedir is set
  770. @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  771. curl_setopt($ch, CURLOPT_COOKIEJAR, 'cache/cookie.curl.txt');
  772. curl_setopt($ch, CURLOPT_COOKIEFILE, 'cache/cookie.curl.txt');
  773. $header = curl_exec($ch);
  774. curl_close($ch);
  775. $header = str_replace(array("\n", "\r"), ' ', $header);
  776. $redirect = strpos($header, 'Location:');
  777. if($redirect!==false)
  778. $url = substr($header, $redirect + strlen('Location:') + 1, strpos($header, " ", $redirect)+1);
  779. $ch = curl_init($url);
  780. $fp = fopen($file, 'w');
  781. curl_setopt($ch, CURLOPT_FILE, $fp);
  782. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  783. curl_setopt($ch, CURLOPT_HEADER, 0);
  784. curl_exec($ch);
  785. curl_close($ch);
  786. fclose($fp);
  787. }
  788. /**
  789. * Removes a folder on the disk and its subfolders
  790. *
  791. * @param string $dir Path of the folder to remove
  792. */
  793. function core_remove_folder($dir)
  794. {
  795. if(is_dir($dir))
  796. {
  797. $objects = scandir($dir);
  798. foreach ($objects as $object)
  799. {
  800. if($object != "." && $object != "..")
  801. {
  802. if(filetype($dir."/".$object) == "dir")
  803. core_remove_folder($dir."/".$object);
  804. else
  805. unlink($dir."/".$object);
  806. }
  807. }
  808. reset($objects);
  809. rmdir($dir);
  810. }
  811. }
  812. /**
  813. * Changes the UNIX permissions of a file or folder and its contents
  814. *
  815. * @param string $path Absolute path to the file or folder to change
  816. * @param string $filemode UNIX permissions code, p.e. 0755
  817. * @return boolean TRUE if no problem found, FALSE otherwise. Note: on Windows systems this function is always FALSE.
  818. */
  819. function core_chmodr($path, $filemode)
  820. {
  821. if (!is_dir($path))
  822. return chmod($path, $filemode);
  823. $dh = opendir($path);
  824. while (($file = readdir($dh)) !== false)
  825. {
  826. if($file != '.' && $file != '..')
  827. {
  828. $fullpath = $path.'/'.$file;
  829. if(is_link($fullpath))
  830. return FALSE;
  831. else if(!is_dir($fullpath) && !chmod($fullpath, $filemode))
  832. return FALSE;
  833. else if(!core_chmodr($fullpath, $filemode))
  834. return FALSE;
  835. }
  836. }
  837. closedir($dh);
  838. if(chmod($path, $filemode))
  839. return TRUE;
  840. else
  841. return FALSE;
  842. }
  843. /**
  844. * Decodes a JSON string removing new lines, tabs, spaces...
  845. *
  846. * @param string $json
  847. * @return object
  848. */
  849. function core_javascript_json($json)
  850. {
  851. $json = trim(substr($json, strpos($json, '{'), -1));
  852. $json = str_replace("\n", "", $json);
  853. $json = str_replace("\r", "", $json);
  854. $json = str_replace("\t", "", $json);
  855. $json = str_replace('"+"', "", $json);
  856. $json = str_replace('" +"', "", $json);
  857. $json = str_replace('"+ "', "", $json);
  858. $json = str_replace('" + "', "", $json);
  859. return json_decode($json);
  860. }
  861. /**
  862. * Completely removes the current session, even the created cookie
  863. *
  864. */
  865. function core_session_remove()
  866. {
  867. if(ini_get("session.use_cookies"))
  868. {
  869. $params = session_get_cookie_params();
  870. setcookie(session_name(), '', time() - 42000,
  871. $params["path"], $params["domain"],
  872. $params["secure"], $params["httponly"]
  873. );
  874. }
  875. @session_destroy();
  876. }
  877. /**
  878. * Shows the last PHP JSON decoding error.
  879. * This function needs APP_DEBUG enabled or the url parameter "debug".
  880. * The error is sent to the Firebug FirePHP plugin within Mozilla Firefox.
  881. *
  882. * @param string $prepend String to prepend before the error (if exists)
  883. */
  884. function debug_json_error($prepend='')
  885. {
  886. $error = '';
  887. if(!empty($prepend))
  888. $prepend .= ' - ';
  889. if(function_exists('json_last_error'))
  890. {
  891. switch (json_last_error())
  892. {
  893. case JSON_ERROR_NONE:
  894. $error = '';
  895. break;
  896. case JSON_ERROR_DEPTH:
  897. $error = 'Maximum stack depth exceeded';
  898. break;
  899. case JSON_ERROR_STATE_MISMATCH:
  900. $error = 'Underflow or the modes mismatch';
  901. break;
  902. case JSON_ERROR_CTRL_CHAR:
  903. $error = 'Unexpected control character found';
  904. break;
  905. case JSON_ERROR_SYNTAX:
  906. $error = 'Syntax error, malformed JSON';
  907. break;
  908. case JSON_ERROR_UTF8:
  909. $error = 'Malformed UTF-8 characters, possibly incorrectly encoded';
  910. break;
  911. default:
  912. $error = 'Unknown error';
  913. break;
  914. }
  915. }
  916. if(!empty($error) && (APP_DEBUG || isset($_REQUEST['debug'])))
  917. debugger::console($prepend.$error);
  918. }
  919. /*
  920. EXAMPLE
  921. $body = navigate_compose_email(
  922. array(
  923. array(
  924. 'title' => "Website",
  925. 'content' => '<a href="' . $website->absolute_path() . $website->homepage() . '">' . $website->name . '</a>'
  926. ),
  927. array(
  928. 'title' => "Content",
  929. 'content' => $content
  930. ),
  931. array(
  932. 'footer' => '<a href="' . $unsubscribe_link . '">Unsubscribe text</a>'
  933. )
  934. )
  935. );
  936. */
  937. function navigate_compose_email($data, $style = array('background' => '#E5F1FF', 'title-color' => '#595959', 'content-color' => '#595959'))
  938. {
  939. global $DB;
  940. $body = array();
  941. if(empty($style))
  942. {
  943. // default colors
  944. $background_color = '#E5F1FF';
  945. $title_color = '#595959';
  946. $text_color = '#595959';
  947. $background_color_db = $DB->query_single('value', 'nv_permissions', 'name = ' . protect("nvweb.comments.background_color") . ' AND website = ' . protect($this->website), 'id DESC');
  948. $text_color_db = $DB->query_single('value', 'nv_permissions', 'name = ' . protect("nvweb.comments.text_color") . ' AND website = ' . protect($this->website), 'id DESC');
  949. $title_color_db = $DB->query_single('value', 'nv_permissions', 'name = ' . protect("nvweb.comments.titles_color") . ' AND website = ' . protect($this->website), 'id DESC');
  950. if (!empty($background_color_db)) $background_color = str_replace('"', '', $background_color_db);
  951. if (!empty($text_color_db)) $text_color = str_replace('"', '', $text_color_db);
  952. if (!empty($title_color_db)) $title_color = str_replace('"', '', $title_color_db);
  953. $style = array(
  954. 'background' => $background_color,
  955. 'title-color' => $title_color,
  956. 'content-color' => $text_color
  957. );
  958. }
  959. $body[] = '<div style=" background: '.$style['background'].'; width: 86%; max-width: 600px; border-radius: 6px; margin: 10px auto; padding: 1px 20px 20px 20px;">';
  960. foreach($data as $section)
  961. {
  962. if(!empty($section['title']))
  963. {
  964. $body[] = '<div style="margin: 25px 0px 10px 0px;">';
  965. $body[] = ' <div style="color: '.$style['title-color'].'; font-size: 17px; font-weight: bold; font-family: Verdana;">'.$section['title'].'</div>';
  966. $body[] = '</div>';
  967. }
  968. if(!empty($section['content']))
  969. {
  970. $body[] = '<div style=" background: #fff; border-radius: 6px; padding: 10px; margin-top: 5px; line-height: 25px; text-align: justify; ">';
  971. $body[] = ' <div class="text" style="color: '.$style['content-color'].'; font-size: 16px; font-style: italic; font-family: Verdana;">'.$section['content'].'</div>';
  972. $body[] = '</div>';
  973. }
  974. if(!empty($section['footer']))
  975. {
  976. $body[] = '<br /><br />';
  977. $body[] = '<div style="color: '.$style['title-color'].';">'.$section['footer'].'</div>';
  978. }
  979. }
  980. $body[] = '</div>';
  981. $body = implode("\n", $body);
  982. return $body;
  983. }
  984. function core_version()
  985. {
  986. global $DB;
  987. global $config;
  988. if(!isset($config['version']))
  989. {
  990. $data = update::latest_installed();
  991. $config['version'] = $data->version;
  992. $config['revision'] = $data->revision;
  993. }
  994. return $config['version'];
  995. }
  996. ?>