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

/lib/general.lib.php

https://github.com/jinzora/jinzora3
PHP | 2704 lines | 1636 code | 326 blank | 742 comment | 426 complexity | 67c4ad2ce1378ed2f99665a131920a30 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php if (!defined(JZ_SECURE_ACCESS)) die ('Security breach detected.');
  2. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  3. * JINZORA | Web-based Media Streamer
  4. *
  5. * Jinzora is a Web-based media streamer, primarily desgined to stream MP3s
  6. * (but can be used for any media file that can stream from HTTP).
  7. * Jinzora can be integrated into a CMS site, run as a standalone application,
  8. * or integrated into any PHP website. It is released under the GNU GPL.
  9. *
  10. * Jinzora Author:
  11. * Ross Carlson: ross@jasbone.com
  12. * http://www.jinzora.org
  13. * Documentation: http://www.jinzora.org/docs
  14. * Support: http://www.jinzora.org/forum
  15. * Downloads: http://www.jinzora.org/downloads
  16. * License: GNU GPL <http://www.gnu.org/copyleft/gpl.html>
  17. *
  18. * Contributors:
  19. * Please see http://www.jinzora.org/modules.php?op=modload&name=jz_whois&file=index
  20. *
  21. * Code Purpose: This page contains all the "general" related functions
  22. * Created: 9.24.03 by Ross Carlson
  23. *
  24. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  25. /**
  26. * Setup the Smarty template system
  27. *
  28. * @author Ross Carlson
  29. * @since 2.27.06
  30. *
  31. **/
  32. function smartySetup(){
  33. global $web_root, $root_dir, $include_path;
  34. $d = dirname(__FILE__);
  35. $root = substr($d, 0, strlen($d)-4) . "/";
  36. defined('SMARTY_DIR') or define('SMARTY_DIR', $root. 'lib/smarty/');
  37. defined('SMARTY_ROOT') or define('SMARTY_ROOT', $root);
  38. require_once(SMARTY_DIR . 'Smarty.class.php');
  39. $smarty = new Smarty;
  40. $smarty->compile_dir = $root. 'temp/';
  41. $smarty->cache_dir = $root. 'temp/';
  42. return $smarty;
  43. }
  44. /*
  45. * Gets a global variable without
  46. * having to declare global.
  47. * Useful for settings.
  48. *
  49. * @author Ben Dodson
  50. * @since 1/30/07
  51. */
  52. function conf($name) {
  53. global $$name;
  54. if (isset($$name)) {
  55. return $$name;
  56. } else {
  57. return null;
  58. }
  59. }
  60. /**
  61. * Verifies that a directory exists and if not creates it
  62. *
  63. * @author Ross Carlson
  64. * @since 11/02/2005
  65. * @param $dir Name of the directory to create
  66. *
  67. **/
  68. function makedir($dir){
  69. $dArr = explode("/",$dir);
  70. $prevDir = "";
  71. foreach($dArr as $dir){
  72. $prevDir .= $dir. "/";
  73. if (!is_dir($prevDir)){
  74. mkdir($prevDir);
  75. }
  76. }
  77. }
  78. /**
  79. * Cleans a potential filename of back characters
  80. *
  81. * @author Ross Carlson
  82. * @since 11/02/2005
  83. * @param $name Name of the track to clean
  84. * @return $ret Cleaned track name
  85. *
  86. **/
  87. function cleanFileName($name){
  88. $badArray = explode(";",';?;";/;\;|;*;<;>;:');
  89. for ($e=0;$e<count($badArray);$e++){
  90. $name = str_replace($badArray[$e],"",$name);
  91. }
  92. return $name;
  93. }
  94. /**
  95. * Grabs the data that was parsed from a Podcast
  96. *
  97. * @author Ross Carlson
  98. * @since 11/02/2005
  99. * @param $item An array with all the values to grab
  100. * @param $folder The subfolder to store the file in
  101. * @return boolean true|false
  102. *
  103. **/
  104. function getPodcastData($item, $folder){
  105. global $include_path, $podcast_folder;
  106. if ($item['file'] == ""){return false;}
  107. $be = new jzBackend();
  108. $display = new jzDisplay();
  109. // Let's clean the new folder name
  110. $folder = trim(cleanFileName($folder));
  111. // Let's grab the file and save it to disk
  112. $ext = substr($item['file'],strlen($item['file'])-3,3);
  113. $track = trim(cleanFileName($item['title']. ".". $ext));
  114. if (substr($podcast_folder,0,1) <> "/"){
  115. $dir = str_replace("\\","/",getcwd()). "/". $podcast_folder. "/". $folder;
  116. } else {
  117. $dir = $podcast_folder. "/". $folder;
  118. }
  119. $track = $dir. "/". $track;
  120. // Now let's create the directory we need
  121. makedir($dir);
  122. // Now let's see if the file already exists
  123. if (!is_file($track)){
  124. ?>
  125. <script language="javascript">
  126. t.innerHTML = '<?php echo word("Downloading"). ": ". $display->returnShortName($item['title'],45); ?>';
  127. -->
  128. </SCRIPT>
  129. <?php
  130. flushdisplay();
  131. // Now let's grab the file and write it out
  132. $fName = str_replace("&amp;","&",$item['file']);
  133. $data = file_get_contents($fName);
  134. $handle = fopen($track, "w");
  135. fwrite($handle,$data);
  136. fclose ($handle);
  137. ?>
  138. <script language="javascript">
  139. t.innerHTML = '<?php echo word("Download Complete!"); ?>';
  140. -->
  141. </SCRIPT>
  142. <?php
  143. flushdisplay();
  144. } else {
  145. ?>
  146. <script language="javascript">
  147. t.innerHTML = '<?php echo word("Exists - moving to next track..."); ?>';
  148. -->
  149. </SCRIPT>
  150. <?php
  151. flushdisplay();
  152. }
  153. return $track;
  154. }
  155. /**
  156. * Parses a given Podcast URL to retrieve all the enclosures
  157. *
  158. * @author Ross Carlson
  159. * @since 11/02/2005
  160. * @param $url The URL to parse
  161. * @return array of the files and descriptions in the XML file
  162. *
  163. **/
  164. function parsePodcastXML($url){
  165. // Let's get the data from the URL
  166. $data = file_get_contents($url);
  167. $c=0;
  168. // Now let's parse out the basics about the feed
  169. $title = substr($data,strpos($data,"<title>")+strlen("<title>"));
  170. $title = substr($title,0,strpos($title,"</title>"));
  171. $desc = substr($data,strpos($data,"<description>")+strlen("<description>"));
  172. $desc = substr($desc,0,strpos($desc,"</description>"));
  173. $pubDate = substr($data,strpos($data,"<pubDate>")+strlen("<pubDate>"));
  174. $pubDate = substr($pubDate,0,strpos($pubDate,"</pubDate>"));
  175. $image = "";
  176. if (stristr($data,"<itunes:image")){
  177. $image = substr($data,strpos($data,"<itunes:image"));
  178. $image = substr($image,strpos($image,'href="')+6);
  179. $image = substr($image,0,strpos($image,'"'));
  180. }
  181. // Now let's set the array
  182. $retArray['title'] = $title;
  183. $retArray['desc'] = $desc;
  184. $retArray['pubDate'] = $pubDate;
  185. $retArray['image'] = $image;
  186. $c++;
  187. // Now let's get the individual items
  188. $items = substr($data,strpos($data,"<item>"));
  189. $iArr = explode("</item>",$items);
  190. // Now let's loop
  191. foreach ($iArr as $item){
  192. // Now let's parse that out
  193. $title = substr($item,strpos($item,"<title>")+strlen("<title>"));
  194. $title = substr($title,0,strpos($title,"</title>"));
  195. $desc = substr($item,strpos($item,"<description>")+strlen("<description>"));
  196. $desc = substr($desc,0,strpos($desc,"</description>"));
  197. $desc = str_replace("]]>","",str_replace("<![CDATA[","",$desc));
  198. $link = substr($item,strpos($item,"<link>")+strlen("<link>"));
  199. $link = substr($link,0,strpos($link,"</link>"));
  200. $pubDate = substr($item,strpos($item,"<pubDate>")+strlen("<pubDate>"));
  201. $pubDate = substr($pubDate,0,strpos($pubDate,"</pubDate>"));
  202. $file = substr($item,strpos($item,'url="')+strlen('url="'));
  203. $file = substr($file,0,strpos($file,'"'));
  204. $length = substr($item,strpos($item,'length="')+strlen('length="'));
  205. $length = substr($length,0,strpos($length,'"'));
  206. // Now let's set the return array
  207. $retArray[$c]['title'] = $title;
  208. $retArray[$c]['link'] = $link;
  209. $retArray[$c]['pubDate'] = $pubDate;
  210. $retArray[$c]['file'] = $file;
  211. $retArray[$c]['desc'] = $desc;
  212. $retArray[$c]['length'] = $length;
  213. $c++;
  214. }
  215. // Now let's return
  216. return $retArray;
  217. }
  218. /*
  219. * Fallback function for stripos
  220. *
  221. * @author Ben Dodson, from PHP.net
  222. * @since 8/31/06
  223. */
  224. if (!function_exists("stripos")) {
  225. function stripos($str,$needle,$offset=0) {
  226. return strpos(strtolower($str),strtolower($needle),$offset);
  227. }
  228. }
  229. /**
  230. * Allows you to write 1 setting to a settings file
  231. *
  232. * @author Ross Carlson
  233. * @since 7/04/2005 - Happy 4th all you Americans!!!
  234. * @param $setting The setting to write
  235. * @param $val The value to write to the setting
  236. * @param $file The file to write too (the full path and filename)
  237. * @return true|false wether the action was successful
  238. *
  239. **/
  240. function writeSetting($setting, $val, $file){
  241. // Now let's open the file and read it in
  242. $fArr = file($file);
  243. // Let's start our new file
  244. $newFile = "";
  245. // Now let's loop through and find the setting
  246. foreach($fArr as $line){
  247. // Now does this line have the setting we want?
  248. if (stristr($line,$setting)){
  249. // Ok we found it, let's change it
  250. $newFile .= substr($line,0,strpos($line," =")). ' = "'. $val. '";'. "\n";
  251. } else {
  252. // Nope, not the line
  253. $newFile .= $line;
  254. }
  255. }
  256. // Now we need to write the file back out
  257. if (is_writable($file)){
  258. $handle = fopen($file, "w");
  259. fwrite($handle,$newFile);
  260. fclose ($handle);
  261. return true;
  262. } else {
  263. return false;
  264. }
  265. }
  266. /**
  267. * Checks the site's general security.
  268. *
  269. * @author Ben Dodson
  270. * @since 6/30/05
  271. *
  272. **/
  273. function checkSecurity() {
  274. // TODO: Check the include file; make sure it is index.php
  275. // or a CMS-specified file.
  276. return;
  277. }
  278. /**
  279. * Makes sure a file is safe to include.
  280. *
  281. * @author Ben Dodson
  282. * @since 8/15/05
  283. *
  284. **/
  285. function includeable_file($fname, $dir = false) {
  286. global $include_path;
  287. if (stristr($fname,'/') !== false) {
  288. return false;
  289. }
  290. if (stristr($fname,"\\") !== false) {
  291. return false;
  292. }
  293. if ($dir !== false) {
  294. $dir = $include_path . $dir;
  295. // make sure it's in $dir.
  296. if (!is_dir($dir)) {
  297. die("$dir is not a valid directory.");
  298. }
  299. $d = dir($dir);
  300. while ($entry = $d->read()) {
  301. if ($entry == $fname) {
  302. return true;
  303. }
  304. }
  305. return false;
  306. }
  307. return true;
  308. }
  309. function emu_getallheaders() {
  310. foreach ($_SERVER as $name => $value)
  311. {
  312. if (substr($name, 0, 5) == 'HTTP_')
  313. {
  314. $name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))));
  315. $headers[$name] = $value;
  316. } else if ($name == "CONTENT_TYPE") {
  317. $headers["Content-Type"] = $value;
  318. } else if ($name == "CONTENT_LENGTH") {
  319. $headers["Content-Length"] = $value;
  320. }
  321. }
  322. return $headers;
  323. }
  324. if (!function_exists('getallheaders')) {
  325. function getallheaders() {
  326. return emu_getallheaders();
  327. }
  328. }
  329. /**
  330. *
  331. * Sets a global variable.
  332. *
  333. * @author Ben Dodson
  334. * @since 6/7/05
  335. *
  336. **/
  337. function setGlobal($var,$val) {
  338. $GLOBALS[$var] = $val;
  339. }
  340. /**
  341. *
  342. * Gets a global variable.
  343. *
  344. * @author Ben Dodson
  345. * @since 6/7/05
  346. *
  347. **/
  348. function getGlobal($var) {
  349. return isset($GLOBALS[$var]) ? $GLOBALS[$var] : false;
  350. }
  351. /**
  352. *
  353. * Takes binary data and writes it to a file
  354. *
  355. * @author Ross Carlson
  356. * @since 3/31/05
  357. * @param $file the name of the file (the full path)
  358. * @param $data the binary data to write to the file
  359. * @param return returns true or false (bolean)
  360. *
  361. **/
  362. function writeImage($file, $data){
  363. global $bad_chars;
  364. foreach ($bad_chars as $item){
  365. str_replace($item,"",$file);
  366. }
  367. if (is_file($file)){ unlink($file); }
  368. $handle = fopen($file, "w");
  369. if (fwrite($handle,$data)){
  370. fclose ($handle);
  371. return true;
  372. } else {
  373. fclose ($handle);
  374. return false;
  375. }
  376. }
  377. /**
  378. * Makes a string safe for XML
  379. * @author php.net
  380. * @since 8/11/05
  381. **/
  382. function htmlnumericentities($str){
  383. return preg_replace('/[^!-%\x27-;=?-~ ]/e', '"&#".ord("$0").chr(59)', $str);
  384. }
  385. function xmlentities($string) {
  386. return str_replace ( array ( '&', '"', "'", '<', '>', '�' ), array ( '&amp;' , '&quot;', '&apos;' , '&lt;' , '&gt;', '&apos;' ), $string );
  387. }
  388. /**
  389. * @author Ben Dodson
  390. *
  391. **/
  392. function sendFileBundle($myfiles, $name) {
  393. global $multiple_download_mode, $download_speed;
  394. $files = array();
  395. foreach ($myfiles as $file) {
  396. if ($file != '' && is_file($file)) {
  397. $files[] = $file;
  398. }
  399. }
  400. if ($files == array()) {
  401. exit();
  402. }
  403. if ($multiple_download_mode == 'tar') {
  404. $reader = &new jzStreamTar($files);
  405. header ('Content-Type: application/x-tar');
  406. header ('Content-Disposition: attachment; filename="' . $name . '.tar"');
  407. } else { // assume zip
  408. $reader = &new jzStreamZip($files);
  409. header ('Content-Type: application/zip');
  410. header ('Content-Disposition: attachment; filename="' . $name . '.zip"');
  411. }
  412. // content length header if supported
  413. if (($size = $reader->FinalSize()) != 0) {
  414. $range = getContentRange($size);
  415. if ($range !== false) {
  416. $range_from = $range[0];
  417. $range_to = $range[1];
  418. } else {
  419. $range_from = 0;
  420. $range_to = $size-1;
  421. }
  422. // BJD 6/30/06:
  423. // HACK: range_to is not supported- only resuming and requesting entire
  424. // remains of file
  425. $range_to = $size-1;
  426. if ($range === false) {
  427. // Content length has already been sent
  428. header("Content-length: ".(string)$size);
  429. } else {
  430. header("HTTP/1.1 206 Partial Content");
  431. header("Accept-Range: bytes");
  432. header("Content-Length: " . ($size - $range_from));
  433. header("Content-Range: bytes $range_from" . "-" . ($range_to) . "/$size");
  434. }
  435. } else {
  436. $range = false;
  437. $range_from = $range_to = 0;
  438. }
  439. // caching headers
  440. header("Cache-control: private");
  441. header("Expires: " . gmdate("D, d M Y H:i:s", mktime(date("H") + 8, date("i"), date("s"), date("m"), date("d"), date("Y"))) . " GMT");
  442. //header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  443. $lastmod = 0;
  444. foreach ($files as $f) {
  445. if (($t = filemtime($f)) > $lastmod) {
  446. $lastmod = $t;
  447. }
  448. }
  449. header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastmod) . " GMT");
  450. header("Pragma: no-cache");
  451. // Let's up the max_execution_time
  452. //ini_set('max_execution_time','6000');
  453. @set_time_limit(0);
  454. // open reader
  455. $reader->Open();
  456. // Are we resuming?
  457. if ($range_from > 0) {
  458. $reader->Read($range_from);
  459. }
  460. // let's send, no speed limit
  461. if ($download_speed == 0 || $download_speed == "") {
  462. while ( ($data=$reader->Read(4096))!='' and connection_status()==0 ) {
  463. echo $data;
  464. flush();
  465. }
  466. } else {
  467. // let's send, looking at the speed
  468. $sent = 0;
  469. $begin_time = get_time();
  470. while ( ($data=$reader->Read(4096))!='' and connection_status()==0 ) {
  471. echo $data;
  472. flush();
  473. $sent += 4;
  474. // if current speed is too high, let's wait a bit
  475. while ($sent/(get_time()-$begin_time) > $download_speed) {
  476. sleep(1);
  477. }
  478. }
  479. }
  480. // close reader
  481. $reader->Close();
  482. @set_time_limit(30);
  483. //write the result in log
  484. if (connection_status() == 0) {
  485. writeLogData('download','download of '.$name.' sucessful');
  486. }
  487. else {
  488. writeLogData('download','download of '.$name.' failed');
  489. }
  490. }
  491. /**
  492. * Displays the image in a browser.
  493. *
  494. *
  495. * @author Ben Dodson
  496. * @version 11/10/04
  497. * @since 11/10/04
  498. */
  499. function showImage ($path) {
  500. global $include_path;
  501. // Now let's see if this is an ID3 image or not
  502. if (stristr($path,"ID3:")){
  503. // Now let's get the data we need
  504. include_once($include_path. 'services/class.php');
  505. $jzSERVICES = new jzServices();
  506. $jzSERVICES->loadStandardServices();
  507. // Now let's fix the path
  508. $path = substr($path,4);
  509. $meta = $jzSERVICES->getTagData($path);
  510. // Now let's set the header
  511. header("Content-Type: ". $meta['pic_mime']);
  512. sendID3Image($path, $meta['pic_name'],$meta['pic_data']);
  513. } else {
  514. $arr = explode("/",$path);
  515. if (sizeof($arr > 0))
  516. $name = $arr[sizeof($arr)-1];
  517. else
  518. $name = $path;
  519. if (substr($path, -3) == "jpg" || substr($path, -4) == "jpeg" || substr($path, -3) == "jpe")
  520. header("Content-Type: image/jpeg");
  521. else if (substr($path, -3) == "gif")
  522. header("Content-Type: image/gif");
  523. else if (substr($path, -3) == "png")
  524. header("Content-Type: image/png");
  525. else if (substr($path, -3) == "bmp")
  526. header("Content-Type: image/bmp");
  527. }
  528. // TODO: GD stuff; synchronize args with jzDisplay::image.
  529. // images are small, so don't worry about handling stream stuff.
  530. streamFile($path,$name);
  531. }
  532. /**
  533. * Sends the content-type header
  534. *
  535. * @author Ben Dodson
  536. * @version 8/17/05
  537. * @since 8/17/05
  538. **/
  539. function sendContentType($ext) {
  540. switch ($ext){
  541. case "mp3":
  542. header("Content-Type: audio/mpeg");
  543. break;
  544. case "wav":
  545. header("Content-Type: audio/x-wav");
  546. break;
  547. case "mpc":
  548. header("Content-Type: application/mpc");
  549. break;
  550. case "wv":
  551. header("Content-Type: application/wv");
  552. break;
  553. case ".ra":
  554. case ".rm":
  555. header("Content-Type: audio/x-pn-realaudio");
  556. break;
  557. case "flac":
  558. header("Content-Type: application/flac");
  559. break;
  560. case "ogg":
  561. header("Content-Type: application/ogg");
  562. break;
  563. case "avi":
  564. header("Content-Type: video/x-msvideo");
  565. break;
  566. case "mpg":
  567. case "mpeg":
  568. header("Content-Type: video/x-mpeg");
  569. break;
  570. case "asf":
  571. case "asx":
  572. case "wma":
  573. case "wmv":
  574. header("Content-Type: video/x-ms-asf");
  575. break;
  576. case "mov":
  577. header("Content-Type: application/x-quicktimeplayer");
  578. break;
  579. case "flv":
  580. header("Content-Type: video/x-flv");
  581. break;
  582. case "mid":
  583. case "midi":
  584. header("Content-Type: audio/midi");
  585. break;
  586. case "aac":
  587. case "mp4":
  588. header("Content-Type: application/x-quicktimeplayer");
  589. break;
  590. }
  591. }
  592. /**
  593. * Sends a clip of a media file.
  594. *
  595. * @author Ben Dodson
  596. * @version 8/17/05
  597. * @since 8/17/05
  598. */
  599. function sendClip($el) {
  600. global $clip_length, $clip_start;
  601. if (!$el->isLeaf()) {
  602. return false;
  603. }
  604. $fname = $el->getFilename("host");
  605. $ext = substr($fname,strrpos($fname,".")+1);
  606. $clipfile = substr($fname,0,-4).".clip." . $ext;
  607. if (is_file($clipfile)) {
  608. sendMedia($clipfile, $el->getName() . " Clip." . $ext);
  609. exit();
  610. }
  611. $meta = $el->getMeta();
  612. $bitrate = $meta['bitrate'];
  613. if (!is_numeric($bitrate)) {
  614. // Let's assume 160.
  615. $bitrate = 160;
  616. }
  617. $cstart = $clip_start * ($bitrate * 1024 / 8);
  618. $clength = $clip_length * ($bitrate * 1024 / 8);
  619. $contents = substr(file_get_contents($fname),$cstart,$clength);
  620. sendContentType($ext);
  621. header("Content-length: " . $clength);
  622. header("Content-Disposition: inline; filename=\"".$el->getName() . " Clip." . $ext."\"");
  623. header("Expires: ".gmdate("D, d M Y H:i:s", mktime(date("H")+2, date("i"), date("s"), date("m"), date("d"), date("Y")))." GMT");
  624. header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
  625. header("Cache-Control: no-cache, must-revalidate");
  626. header("Pragma: no-cache");
  627. print $contents;
  628. exit();
  629. }
  630. /**
  631. * Sends the actual media file
  632. * and possibly resamples it.
  633. *
  634. *
  635. * @author Ben Dodson
  636. * @version 11/11/04
  637. * @since 11/11/04
  638. */
  639. function sendMedia($path, $name, $resample=false, $download = false) {
  640. // Let's get the extension from the file
  641. $extArr = explode(".",$path);
  642. $ext = $extArr[count($extArr)-1];
  643. // Now let's fix up the name
  644. if (substr($name,0-strlen($ext)-1) != "." . $ext) {
  645. $name .= "." . $ext;
  646. }
  647. if ($resample != "") {
  648. $ext = false;
  649. }
  650. // TODO: resample.
  651. // probably make a different streamFile (streamResampled)
  652. streamFile($path,$name,false,$resample,$download, true, $ext);
  653. }
  654. /**
  655. * Sends the ID3 image
  656. *
  657. * @author Ben Dodson
  658. * @version 7/20/05
  659. * @since 7/20/05
  660. **/
  661. function sendID3Image($path,$name,$id3) {
  662. header("Content-length: ".(string)(strlen($id3)));
  663. header("Content-Disposition: inline; filename=\"".$name."\"");
  664. header("Expires: ".gmdate("D, d M Y H:i:s", mktime(date("H")+2, date("i"), date("s"), date("m"), date("d"), date("Y")))." GMT");
  665. header("Last-Modified: ".gmdate("D, d M Y H:i:s", filemtime($path))." GMT");
  666. header("Cache-Control: no-cache, must-revalidate");
  667. header("Pragma: no-cache");
  668. print($id3);
  669. return true;
  670. }
  671. /**
  672. * Actually sends the data in the specified file.
  673. *
  674. *
  675. * @author Ben Dodson, PHP.net
  676. * @version 11/11/04
  677. * @since 11/11/04
  678. */
  679. function streamFile($path,$name,$limit=false,$resample="",$download = false, $contentTypeFor = false) {
  680. global $always_resample, $allow_resample, $always_resample_rate, $jzUSER;
  681. // Let's ignore if they abort, that way we'll know when the track stops...
  682. ignore_user_abort(TRUE);
  683. $jzSERVICES = new jzServices();
  684. $jzSERVICES->loadStandardServices();
  685. $status = false;
  686. if ($limit === false)
  687. $speed_limit = 1*1024; // from system.php?
  688. else
  689. $speed_limit = $limit;
  690. // limit is passed as a param because we may want to limit it for downloads
  691. // but not for streaming / image viewing.
  692. // Also, we may want to write a different function for resampling,
  693. // but I don't know yet.
  694. // IF NO SPEED LIMIT:
  695. // the 'speed_limit' from above is the amount
  696. // of buffer used while sending the file.
  697. // but with no speed limit, there is no 'sleep' issued.
  698. // this makes seeking in a file much faster.
  699. // Let's get the extension of the real file
  700. $extArr = explode(".",$path);
  701. $ext = $extArr[count($extArr)-1];
  702. if (!is_file($path) || connection_status() != 0) return (false);
  703. $meta = $jzSERVICES->getTagData($path);
  704. $do_resample = false;
  705. if (!isNothing($resample)) {
  706. $do_resample = true;
  707. }
  708. if (($allow_resample == "true") && stristr($always_resample,$ext)) {
  709. $do_resample = true;
  710. }
  711. if ($meta['type'] == "mp3") {
  712. if (!isNothing($resample) && $resample >= $meta['bitrate']) {
  713. $do_resample = false;
  714. }
  715. }
  716. if ($download) {
  717. $do_resample = false;
  718. }
  719. // Are they resampling or transcoding?
  720. if ($do_resample){
  721. // Ok, if resampling isn't set let's go with the default
  722. if ($resample == ""){
  723. $resample = $always_resample_rate;
  724. }
  725. // Now let's load up the resampling service
  726. $jzSERVICES = new jzServices();
  727. $jzSERVICES->loadService("resample","resample");
  728. $jzSERVICES->resampleFile($path,$name,$resample);
  729. // Now let's unset what they are playing
  730. $be = new jzBackend();
  731. $be->unsetPlaying($_GET['jz_user'],$_GET['sid']);
  732. return;
  733. }
  734. // Now we need to know if this is an ID3 image or not
  735. // First let's get their limit
  736. $limit = "7";
  737. $size = filesize($path);
  738. $range = getContentRange($size);
  739. if ($range !== false) {
  740. $range_from = $range[0];
  741. $range_to = $range[1];
  742. } else {
  743. $range_from = 0;
  744. $range_to = $size-1;
  745. }
  746. $ps3 = false;
  747. $allheaders = getallheaders();
  748. if (isset($allheaders['User-Agent']) && $allheaders['User-Agent'] == "PLAYSTATION 3") {
  749. $ps3 = true;
  750. }
  751. if ($ps3) {
  752. // ps3 is picky and bizarre.
  753. if ($range_from > $size) {
  754. // This happens if the ps3 thinks the file
  755. // is larger than it is, and sending a
  756. // This is supposed to be a read of the id3v1 tag at
  757. // the end of a file (128 bytes), or the lyrics tag
  758. // (138 bytes)
  759. $requested = $range_to - $range_from + 1;
  760. $range_from = $size - $requested;
  761. $range_to = $size - 1;
  762. header("HTTP/1.1 206 Partial content");
  763. } else if ($range_from == 0 && $size == $range_to + 1) {
  764. header("HTTP/1.1 200 OK");
  765. } else {
  766. header("HTTP/1.1 206 Partial content");
  767. header("CONTENT-RANGE: bytes ${range_from}-${range_to}/${size}");
  768. }
  769. header("transferMode.dlna.org: Streaming");
  770. header("contentFeatures.dlna.org: DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=017000 00000000000000000000000000");
  771. header("Accept-Ranges: bytes");
  772. header("Connection: keep-alive");
  773. header("Content-Length: " . ($size - $range_from));
  774. } else if ($range === false) {
  775. // Content length has already been sent
  776. header("Content-Length: ".(string)$size);
  777. } else {
  778. header("HTTP/1.1 206 Partial Content");
  779. header("Accept-Range: bytes");
  780. header("Content-Length: " . ($size - $range_from));
  781. header("Content-Range: bytes $range_from" . "-" . ($range_to) . "/$size");
  782. }
  783. if ($contentTypeFor !== false) {
  784. sendContentType($contentTypeFor);
  785. }
  786. if (!$ps3) {
  787. header("Content-Disposition: inline; filename=\"".$name."\"");
  788. header("Expires: ".gmdate("D, d M Y H:i:s", mktime(date("H")+2, date("i"), date("s"), date("m"), date("d"), date("Y")))." GMT");
  789. header("Last-Modified: ".gmdate("D, d M Y H:i:s", filemtime($path))." GMT");
  790. header("Cache-Control: no-cache, must-revalidate");
  791. header("Pragma: no-cache");
  792. }
  793. if ($file = fopen($path, 'rb')) {
  794. @set_time_limit(0);
  795. fseek($file, $range_from);
  796. while(!feof($file) and (connection_status()==0) and ($cur_pos = ftell($file)) < $range_to+1) {
  797. print(fread($file, min(1024*$speed_limit, $range_to + 1 - $cur_pos)));
  798. flush();
  799. if ($limit !== false) {
  800. sleep(1);
  801. }
  802. }
  803. $status = (connection_status()==0);
  804. fclose($file);
  805. @set_time_limit(30);
  806. }
  807. // Now let's unset what they are playing
  808. $be = new jzBackend();
  809. $be->unsetPlaying($_GET['jz_user'],$_GET['sid']);
  810. return($status);
  811. }
  812. /**
  813. * Converts an associative array to a link.
  814. * Function can take 2 arrays and treats them both the same.
  815. * Useful if you have a set of variables that you use a lot
  816. * and another set you use only once or twice.
  817. *
  818. * This function also remembers things like GET-based frontend/theme settings.
  819. *
  820. * @author Ben Dodson
  821. * @version 11/6/04
  822. * @since 11/5/04
  823. */
  824. function urlize($arr1 = array(), $arr2 = array()) {
  825. global $this_page, $root_dir, $link_root, $include_path, $ssl_stream, $secure_urls,$jzUSER;
  826. $this_page = setThisPage();
  827. $arr = $arr1 + $arr2;
  828. if (!isset($arr['action'])) {
  829. $action="";
  830. } else {
  831. $action = $arr['action'];
  832. }
  833. if (isset($arr['jz_path']) && $arr['jz_path'] == "") {
  834. unset($arr['jz_path']);
  835. }
  836. if ($action != "play" && $action != "playlist") {
  837. if (isset($_GET['frontend']) && !isset($arr['frontend'])) {
  838. $arr['frontend'] = $_GET['frontend'];
  839. } else if (isset($_POST['frontend']) && !isset($arr['frontend'])) {
  840. $arr['frontend'] = $_POST['frontend'];
  841. }
  842. if (isset($_GET['theme']) && $_GET['theme'] != '' && !isset($arr['theme'])) {
  843. $arr['theme'] = $_GET['theme'];
  844. } else if (isset($_POST['theme']) && $_POST['theme'] != '' && !isset($arr['theme'])) {
  845. $arr['theme'] = $_POST['theme'];
  846. }
  847. }
  848. switch ($action) {
  849. case "play":
  850. $link = "";
  851. if ($ssl_stream == "true") {
  852. $link .= "https://";
  853. } else {
  854. $link .= "http://";
  855. }
  856. $link .= $_SERVER['HTTP_HOST'];
  857. if ($_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443 && (strpos($link,":") === false)) {
  858. $link .= ":" . $_SERVER['SERVER_PORT'];
  859. }
  860. $link = str_replace(":443","",$link);
  861. $link .= $root_dir . "/mediabroadcast.php?";
  862. $ENC_FUNC = "jz_track_encode";
  863. // fairly gross hack for non-mp3 files:
  864. if (isset($arr['ext'])) {
  865. $extension = $arr['ext'];
  866. unset($arr['ext']);
  867. } else {
  868. $extension = false;
  869. }
  870. break;
  871. case "image":
  872. //case "download":
  873. $link = "";
  874. if ($_SERVER['SERVER_PORT'] == 443) {
  875. $link .= "https://";
  876. } else {
  877. $link .= "http://";
  878. }
  879. $link .= $_SERVER['HTTP_HOST'];
  880. if ($_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443 && (strpos($link,":") === false)) {
  881. $link .= ":" . $_SERVER['SERVER_PORT'];
  882. }
  883. $link = str_replace(":443","",$link);
  884. $link .= $root_dir . "/mediabroadcast.php?image=tr&";
  885. $ENC_FUNC = "jz_encode";
  886. // fairly gross hack for non-mp3 files:
  887. if (isset($arr['ext'])) {
  888. $extension = $arr['ext'];
  889. unset($arr['ext']);
  890. } else {
  891. $extension = false;
  892. }
  893. break;
  894. case "popup":
  895. $link = $root_dir . "/popup.php?";
  896. $ENC_FUNC = "jz_encode";
  897. $extension = false;
  898. break;
  899. default:
  900. $link = $this_page; // setThisPage handles CMS stuff and adds & or ?.
  901. $ENC_FUNC = "jz_encode";
  902. $extension = false;
  903. }
  904. if ($action == "playlist") {
  905. $extension = $jzUSER->getSetting('playlist_type');
  906. }
  907. //$jz_secure = "true"; // for now.
  908. $vars="";
  909. if ($secure_urls == "true" && !url_full_exception($arr)) {
  910. foreach ($arr as $key => $val) {
  911. // if jz_secure, jz_encode our keys and vars.
  912. if (!url_key_exception($key))
  913. $vars .= "&" . urlencode($ENC_FUNC($key)) . "=" . urlencode($ENC_FUNC($val));
  914. else
  915. $vars .= "&" . urlencode($key) . "=" . urlencode($val);
  916. }
  917. } else {
  918. foreach ($arr as $key => $val) {
  919. $vars .= "&" . urlencode($key) . "=" . urlencode($val);
  920. }
  921. }
  922. $link = $link . substr($vars,1);
  923. if (!isNothing($extension)) {
  924. $link .= "&ext." . $extension;
  925. } else {
  926. $link .= "&ext.html";
  927. }
  928. return $link;
  929. }
  930. /**
  931. * Gets the URL root from a URLized string.
  932. *
  933. * @author Ben Dodson
  934. * @since 7/16/06
  935. * @version 7/16/06
  936. */
  937. function getURLRoot($url) {
  938. return substr($url, 0, strpos($url,'?'));
  939. }
  940. /**
  941. * Gets the URL root from a URLized string.
  942. *
  943. * @author Ben Dodson
  944. * @since 7/16/06
  945. * @version 7/16/06
  946. */
  947. function getURLVars($url) {
  948. $url = substr($url, strpos($url,'?')+1);
  949. $url = explode("&",$url);
  950. $url2 = array();
  951. foreach ($url as $var){
  952. $url2[substr($var,0,strpos($var,'='))] =
  953. substr($var,strpos($var,'=')+1);
  954. }
  955. return $url2;
  956. }
  957. /**
  958. * Inverse of the above.
  959. *
  960. * @author Ben Dodson
  961. * @version 11/11/04
  962. * @since 11/11/04
  963. */
  964. function unurlize($arr) {
  965. global $secure_urls;
  966. $GET = array();
  967. if (false !== stristr($_SERVER['PHP_SELF'],"mediabroadcast.php")) {
  968. if (isset($arr['image'])) {
  969. $DEC_FUNC = "jz_decode";
  970. } else {
  971. $DEC_FUNC = "jz_track_decode";
  972. }
  973. } else {
  974. $DEC_FUNC = "jz_decode";
  975. }
  976. //$jz_secure = "true";
  977. if ($secure_urls == "true" && !url_full_exception($arr)) {
  978. foreach ($arr as $key => $val) {
  979. // if jz_secure, jz_encode our keys and vars.
  980. if (!url_key_exception($key) && !is_array($key)) {
  981. $GET[$DEC_FUNC($key)] = $DEC_FUNC(stripSlashes($val));
  982. } else if (!is_array($key)) {
  983. $GET[$key] = stripSlashes($val);
  984. } else {
  985. $GET[$key] = $val;
  986. }
  987. }
  988. } else {
  989. foreach ($arr as $key => $val) {
  990. if (!is_array($key)) {
  991. $GET[$key] = stripSlashes($val);
  992. } else {
  993. $GET[$key] = $val;
  994. }
  995. }
  996. }
  997. return $GET;
  998. }
  999. /**
  1000. * Same as above for POST variables.
  1001. *
  1002. * @author Ben Dodson
  1003. * @version 12/16/04
  1004. * @ since 12/16/04
  1005. */
  1006. function unpostize($arr) {
  1007. $POST = array();
  1008. if (url_full_exception($arr)) {
  1009. foreach($arr as $key => $val) {
  1010. $POST[$key] = stripSlashes($val);
  1011. }
  1012. }
  1013. else {
  1014. foreach ($arr as $key => $val) {
  1015. if (is_array($val)) {
  1016. $arr1 = array();
  1017. for ($i = 0; $i < sizeof($val); $i++) {
  1018. $arr1[] = stripSlashes(jz_decode($val[$i]));
  1019. }
  1020. $POST[$key] = $arr1;
  1021. } else if (post_key_exception($key)) {
  1022. $POST[$key] = stripSlashes($val);
  1023. } else {
  1024. $POST[jz_decode($key)] = jz_decode(stripSlashes($val));
  1025. }
  1026. }
  1027. }
  1028. return $POST;
  1029. }
  1030. /**
  1031. * Checks to see if a key indicates our entire string should not be scrambled.
  1032. *
  1033. * @author Ben Dodson
  1034. * @version 11/11/04
  1035. * @since 11/11/04
  1036. */
  1037. function url_full_exception($arr) {
  1038. foreach ($arr as $key => $val) {
  1039. switch ($key) {
  1040. // if we see doSearch, don't unscramble/scramble since we
  1041. // came from searchbar
  1042. case "doSearch":
  1043. if (isset($_REQUEST['action']) && $_REQUEST['action'] != '' ) {
  1044. if ($_REQUEST['action'] != "search") {
  1045. die("Not allowed.");
  1046. }
  1047. }
  1048. return true;
  1049. break;
  1050. case "update_settings":
  1051. /* This will break if you try to update_settings
  1052. * outside of a popup.
  1053. */
  1054. if (isset($_REQUEST['action'])) {
  1055. if ($_REQUEST['action'] != "popup") {
  1056. die("Not allowed.");
  1057. }
  1058. }
  1059. /* Just so you know.
  1060. */
  1061. return true;
  1062. break;
  1063. }
  1064. }
  1065. return false;
  1066. }
  1067. /**
  1068. * Checks to see if our key/val string should be scrambled.
  1069. * Things like text inputs are not scrambled.
  1070. *
  1071. * @author Ben Dodson
  1072. * @version 11/11/04
  1073. * @since 11/11/04
  1074. */
  1075. function url_key_exception($key) {
  1076. global $jzSERVICES;
  1077. $a = $jzSERVICES->cmsGETVars();
  1078. if (isset($a[$key])) return true;
  1079. switch ($key) {
  1080. case "query":
  1081. case "search_query":
  1082. case "Artist": // decoy
  1083. case "Track": // decoy
  1084. case "Title": // decoy
  1085. case "op":
  1086. case "name":
  1087. case "frame":
  1088. case "jza":
  1089. case "view":
  1090. case "style":
  1091. case "user":
  1092. case "pass":
  1093. case "playlistname":
  1094. //case "file":
  1095. return true;
  1096. }
  1097. return false;
  1098. }
  1099. /** Same as above, but for POST variables.
  1100. *
  1101. * @author Ben Dodson
  1102. * @version 12/16/04
  1103. * @since 12/16/04
  1104. */
  1105. function post_key_exception($key) {
  1106. // Let's account for some partial matches
  1107. if (stristr($key,"plTrackPos-")
  1108. or stristr($key,"plTrackDel-")
  1109. or stristr($key,"edit_")
  1110. ){
  1111. return true;
  1112. }
  1113. switch ($key) {
  1114. case "update_postsettings":
  1115. case "jz_list":
  1116. case "query":
  1117. case "search_query":
  1118. case "field1":
  1119. case "field2":
  1120. case "field3":
  1121. case "field4":
  1122. case "field5":
  1123. case "remember":
  1124. case "siteNewsData":
  1125. case "jbvol":
  1126. case "jbplaywhere":
  1127. case "jbjumpto":
  1128. case "addplat":
  1129. case "jz_playlist":
  1130. case "playlistname":
  1131. case "updateTags":
  1132. case "reGenre":
  1133. case "reArtist":
  1134. case "reAlbum":
  1135. case "reTrack":
  1136. case "reNumber":
  1137. case "plType":
  1138. case "shareWithUser":
  1139. case "updatePlaylist":
  1140. case "deletePlaylist":
  1141. case "plToEdit":
  1142. case "randomize":
  1143. return true;
  1144. default:
  1145. return false;
  1146. }
  1147. }
  1148. /**
  1149. * Scrambles a string
  1150. *
  1151. * @author Ben Dodson
  1152. * @version 11/6/04
  1153. * @since 11/6/04
  1154. */
  1155. function jz_encode($string, $key = false) {
  1156. global $secure_urls,$security_key;
  1157. if ($secure_urls == "false"){
  1158. return $string;
  1159. }
  1160. // Complex scheme.
  1161. if ($key === false) {
  1162. $key = $security_key;
  1163. if (strlen($key) < 10) {
  1164. $key = "secrets are fun to keep (so let's keep them)";
  1165. }
  1166. }
  1167. $result = '';
  1168. for($i=1; $i<=strlen($string); $i++) {
  1169. $char = substr($string, $i-1, 1);
  1170. $keychar = substr($key, ($i % strlen($key))-1, 1);
  1171. $char = chr(ord($char)+ord($keychar));
  1172. $result .= $char;
  1173. }
  1174. return str_replace("+","JZPLUS",base64_encode($result));
  1175. }
  1176. /**
  1177. * Unscrambles a string.
  1178. *
  1179. * @author Ben Dodson
  1180. * @version 11/6/04
  1181. * @since 11/5/04
  1182. */
  1183. function jz_decode($string, $key = false) {
  1184. global $secure_urls,$security_key;
  1185. if ($secure_urls == "false"){
  1186. return $string;
  1187. }
  1188. // Complex scheme.
  1189. $string = base64_decode(str_replace("JZPLUS","+",$string));
  1190. if ($key === false) {
  1191. $key = $security_key;
  1192. if (strlen($key) < 10) {
  1193. $key = "secrets are fun to keep (so let's keep them)";
  1194. }
  1195. }
  1196. $result = '';
  1197. for ($i=1; $i <= strlen($string); $i++) {
  1198. $char = substr($string,$i-1,1);
  1199. $keychar = substr($key,($i % strlen($key))-1,1);
  1200. $char = chr(ord($char)-ord($keychar));
  1201. $result .= $char;
  1202. }
  1203. return $result;
  1204. }
  1205. /*
  1206. * Encodes the URL for a track (since players break easily)
  1207. *
  1208. * @author Ben Dodson
  1209. * @since 2/2/05
  1210. * @version 2/2/05
  1211. *
  1212. **/
  1213. function jz_track_encode($string) {
  1214. $ret = "";
  1215. return strrev($string);
  1216. for ($i = 0; $i < strlen($string); $i++) {
  1217. $ret .= chr(ord($string[$i])+4);
  1218. }
  1219. return strrev($ret);
  1220. }
  1221. /*
  1222. * Decodes the URL for a track (since players break easily)
  1223. *
  1224. * @author Ben Dodson
  1225. * @since 2/2/05
  1226. * @version 2/2/05
  1227. *
  1228. **/
  1229. function jz_track_decode($string) {
  1230. $ret = "";
  1231. return strrev($string);
  1232. $string = strrev($string);
  1233. for ($i = 0; $i < strlen($string); $i++) {
  1234. $ret .= chr(ord($string[$i])-4);
  1235. }
  1236. return $ret;
  1237. }
  1238. function getTrackIdFromURL($url) {
  1239. global $secure_urls;
  1240. if ($secure_urls == "true") {
  1241. $decoded_label = jz_track_encode('jz_path');
  1242. } else {
  1243. $decoded_label = 'jz_path';
  1244. }
  1245. $args = substr($url,strpos($url,'?')+1);
  1246. $args = explode('&',$args);
  1247. foreach ($args as $arg) {
  1248. $parts = explode('=',$arg);
  1249. if ($parts[0] == $decoded_label) {
  1250. if ($secure_urls == "true") {
  1251. return jz_track_decode($parts[1]);
  1252. } else {
  1253. return $parts[1];
  1254. }
  1255. }
  1256. }
  1257. return false;
  1258. }
  1259. /**
  1260. * Scrambles a string for the cookie
  1261. *
  1262. * @author Ben Dodson
  1263. * @version 1/16/05
  1264. * @since 11/23/04
  1265. */
  1266. function jz_cookie_encode($string) {
  1267. return jz_encode($string, "this is a secret key that will be moved and improved.");
  1268. }
  1269. /**
  1270. * Unscrambles a stringf or the cookie
  1271. *
  1272. * @author Ben Dodson
  1273. * @version 1/16/05
  1274. * @since 11/23/04
  1275. */
  1276. function jz_cookie_decode($string) {
  1277. return jz_decode($string, "this is a secret key that will be moved and improved.");
  1278. }
  1279. function setThisPage() {
  1280. global $link_root, $cms_type, $cms_mode, $fe;
  1281. if (defined('JZ_URL_OVERRIDE')) {
  1282. $link = JZ_URL_OVERRIDE . '?';
  1283. } else if ($cms_mode === false || $cms_mode == "false" || $link_root == "") {
  1284. //$a = explode("/",$_SERVER['PHP_SELF']);
  1285. //$link = $a[sizeof($a)-1] . '?';
  1286. $link = $_SERVER['PHP_SELF'];
  1287. $link = substr($link,0,strrpos($link,'/')).'/index.php?';
  1288. $link = str_replace("popup.php","index.php",$link);
  1289. }
  1290. else {
  1291. //
  1292. $link = $link_root;
  1293. }
  1294. // check for things that need to be added:
  1295. $this_page = $link;
  1296. // Add additional settings to our URL:
  1297. if (isset($_GET['set_frontend'])) {
  1298. $this_page .= urlencode(jz_encode("frontend")) . "=" . urlencode(jz_encode($_GET['set_frontend'])) . "&";
  1299. $_GET['frontend'] = $_GET['set_frontend'];
  1300. } else if (isset($_POST['set_frontend'])) {
  1301. $this_page .= urlencode(jz_encode("frontend")) . "=" . urlencode(jz_encode($_POST['set_frontend'])) . "&";
  1302. $_GET['frontend'] = $_POST['set_frontend'];
  1303. } else if (isset($_GET['view'])) {
  1304. $this_page .= urlencode(jz_encode("frontend")) . "=" . urlencode(jz_encode($_GET['view'])) . "&";
  1305. $_GET['frontend'] = $_GET['view'];
  1306. } else if (isset($_GET['frontend'])) {
  1307. $this_page .= urlencode(jz_encode("frontend")) . "=" . urlencode(jz_encode($_GET['frontend'])) . "&";
  1308. }
  1309. if (isset($_GET['set_theme'])) {
  1310. $this_page .= urlencode(jz_encode("theme")) . "=" . urlencode(jz_encode($_GET['set_theme'])) . "&";
  1311. $_GET['theme'] = $_GET['set_theme'];
  1312. } else if (isset($_POST['set_theme'])) {
  1313. $this_page .= urlencode(jz_encode("theme")) . "=" . urlencode(jz_encode($_POST['set_theme'])) . "&";
  1314. $_GET['theme'] = $_POST['set_theme'];
  1315. } else if (isset($_GET['style'])) {
  1316. $this_page .= urlencode(jz_encode("theme")) . "=" . urlencode(jz_encode($_GET['style'])) . "&";
  1317. $_GET['theme'] = $_GET['style'];
  1318. } else if (isset($_GET['theme'])) {
  1319. $this_page .= urlencode(jz_encode("theme")) . "=" . urlencode(jz_encode($_GET['theme'])) . "&";
  1320. }
  1321. if (isset($_GET['set_language'])) {
  1322. $this_page .= urlencode(jz_encode("language")) . "=" . urlencode(jz_encode($_GET['set_language'])) . "&";
  1323. $_GET['language'] = $_GET['set_language'];
  1324. } else if (isset($_POST['set_language'])) {
  1325. $this_page .= urlencode(jz_encode("language")) . "=" . urlencode(jz_encode($_POST['set_language'])) . "&";
  1326. $_GET['language'] = $_POST['set_language'];
  1327. } else if (isset($_GET['language'])) {
  1328. $this_page .= urlencode(jz_encode("language")) . "=" . urlencode(jz_encode($_GET['language'])) . "&";
  1329. }
  1330. return $this_page;
  1331. }
  1332. /**
  1333. * Replace ob_flush()
  1334. *
  1335. * @category PHP
  1336. * @package PHP_Compat
  1337. * @link http://php.net/function.ob_flush
  1338. * @author Aidan Lister <aidan@php.net>
  1339. * @author Thiemo M�ttig (http://maettig.com/)
  1340. * @version $Revision$
  1341. * @since PHP 4.2.0
  1342. * @require PHP 4.0.1 (trigger_error)
  1343. */
  1344. if (!function_exists('ob_flush'))
  1345. {
  1346. function ob_flush()
  1347. {
  1348. if (@ob_end_flush()) {
  1349. return ob_start();
  1350. }
  1351. trigger_error("ob_flush() Failed to flush buffer. No buffer to flush.", E_USER_NOTICE);
  1352. return false;
  1353. }
  1354. }
  1355. /**
  1356. * Replace file_get_contents()
  1357. *
  1358. * @category PHP
  1359. * @package PHP_Compat
  1360. * @link http://php.net/function.file_get_contents
  1361. * @author Aidan Lister <aidan@php.net>
  1362. * @version $Revision$
  1363. * @internal resource_context is not supported
  1364. * @since PHP 5
  1365. * @require PHP 4.0.1 (trigger_error)
  1366. */
  1367. if (!function_exists('file_get_contents'))
  1368. {
  1369. function file_get_contents($filename, $incpath = false, $resource_context = null)
  1370. {
  1371. if (false === $fh = fopen($filename, 'rb', $incpath)) {
  1372. trigger_error('file_get_contents() failed to open stream: No such file or directory', E_USER_WARNING);
  1373. return false;
  1374. }
  1375. clearstatcache();
  1376. if ($fsize = filesize($filename)) {
  1377. $data = fread($fh, $fsize);
  1378. } else {
  1379. while (!feof($fh)) {
  1380. $data .= fread($fh, 8192);
  1381. }
  1382. }
  1383. fclose($fh);
  1384. return $data;
  1385. }
  1386. }
  1387. // microtime for PHP 4
  1388. function microtime_float()
  1389. {
  1390. list($usec, $sec) = explode(" ", microtime());
  1391. return ((float)$usec + (float)$sec);
  1392. }
  1393. /**
  1394. * Returns a list of available languages
  1395. *
  1396. * @author Ben Dodson, Ross Carlson
  1397. * @since 11/5/05
  1398. *
  1399. */
  1400. function getLanguageList() {
  1401. global $include_path;
  1402. $lang_dir = $include_path. "lang";
  1403. $retArray = readDirInfo($lang_dir,"file");
  1404. sort($retArray);
  1405. $languages = array();
  1406. for ($c=0; $c < count($retArray); $c++){
  1407. $entry = $retArray[$c];
  1408. // Let's make sure this isn't the local directory we're looking at
  1409. if ($entry == "." || $entry == ".." || $entry == "master.php") { continue;}
  1410. if (!stristr($entry,"-setup") and !stristr($entry,".html")){
  1411. if (strrpos($entry,'-') !== false) {
  1412. $languages[substr($entry,0,strrpos($entry,'-'))] = true;
  1413. } else {
  1414. $languages[$entry] = true;
  1415. }
  1416. }
  1417. }
  1418. return array_keys($languages);
  1419. }
  1420. /**
  1421. * Translates a word into a native language
  1422. *
  1423. *
  1424. * @author Ross Carlson
  1425. * @author Ben Dodson
  1426. * @version 3.22.05
  1427. * @since 3.22.05
  1428. * @param string $word The word to translate
  1429. * @param $term1, $term2, ....: replace the key %s in $word.
  1430. */
  1431. function word($word){
  1432. global $words, $jz_lang_file, $include_path;
  1433. // Let's hash that word
  1434. $hash = md5($word);
  1435. // Now let's make sure there is a translation for this
  1436. if (isset($words[$hash])){
  1437. $ret = $words[$hash];
  1438. } else {
  1439. // Ok, it didn't so let's log it and return what they put it
  1440. $fileName = $include_path. "temp/jinzora-words-". $jz_lang_file. ".log";
  1441. if (!is_file($fileName)){touch($fileName);}
  1442. $data = file_get_contents($fileName);
  1443. if (!stristr($data,$word)){
  1444. $handle = @fopen($fileName, "a");
  1445. $data = "$". "words['". $hash. "'] = ". '"'. $word. '";'. "\n";
  1446. @fwrite($handle,$data);
  1447. @fclose($handle);
  1448. }
  1449. // Now let's set up for returning:
  1450. $ret = $word;
  1451. }
  1452. // Replace %s as needed:
  1453. $i = 1;
  1454. while (($index = strpos($ret,'%s')) !== false) {
  1455. $ret = substr($ret,0,$index) . func_get_arg($i++) . substr($ret,$index+2);
  1456. }
  1457. return $ret;
  1458. }
  1459. // This function will see if there is a thumbnail for the corresponding item
  1460. // Added 3.23.04 by Ross Carlson
  1461. // It returns false or the name of the file
  1462. function searchThumbnail($searchFile){
  1463. global $ext_graphic, $web_root;
  1464. $typeArray = explode("|",$ext_graphic);
  1465. $thumb_file = "";
  1466. $fileExt = returnFileExt($searchFile);
  1467. for ($e=0; $e < count($typeArray); $e++){
  1468. $thumbFileName = str_replace(".".$fileExt,".thumb.". $typeArray[$e],$searchFile);
  1469. if (is_file($thumbFileName)){
  1470. $thumb_file = str_replace("%2F","/",rawurlencode(str_replace($web_root,"",$thumbFileName)));
  1471. }
  1472. }
  1473. // Now let's return it
  1474. if ($thumb_file <> ""){
  1475. return $thumb_file;
  1476. } else {
  1477. return false;
  1478. }
  1479. }
  1480. /**
  1481. * Display the opening tag for a table
  1482. *
  1483. * @author Ross Carlson
  1484. * @version 04/28/04
  1485. * @since 04/28/04
  1486. * @param integer $width Width of the table in percent
  1487. * @param integer $cellpadding cellpadding for the table
  1488. * @param string $class the style sheet class for the table
  1489. */
  1490. function jzTableOpen($width = "100", $cellpadding = "5", $class = "jz_track_table", $widthType = "%"){
  1491. echo '<table class="'. $class. '" width="'. $width. $widthType. '" cellpadding="'. $cellpadding. '" cellspacing="0" border="0">'. "\n";
  1492. }
  1493. /**
  1494. * Display the closing tag for a table
  1495. *
  1496. * @author Ross Carlson
  1497. * @version 04/28/04
  1498. * @since 04/28/04
  1499. */
  1500. function jzTableClose(){
  1501. echo '</table>'. "\n";
  1502. }
  1503. /**
  1504. * open a Table Row
  1505. *
  1506. * @author Ross Carlson
  1507. * @version 04/28/04
  1508. * @since 04/28/04
  1509. * @param string $class the style sheet class for the table
  1510. */
  1511. function jzTROpen($class = ""){
  1512. echo ' <tr class="'. $class. '">'. "\n";
  1513. }
  1514. /**
  1515. * close a Table Row
  1516. *
  1517. * @author Ross Carlson
  1518. * @version 04/28/04
  1519. * @since 04/28/04
  1520. */
  1521. function jzTRClose(){
  1522. echo ' </tr>'. "\n";
  1523. }
  1524. /**
  1525. * Display the opening tag for a table detail
  1526. *
  1527. * @author Ross Carlson
  1528. * @version 04/28/04
  1529. * @since 04/28/04
  1530. * @param integer $width Width of the table in percent
  1531. * @param string $align alignment for the cell
  1532. * @param string $valign verticle alignment for the cell
  1533. * @param string $class the style sheet class for the table
  1534. * @param integer $colspan how many colums should this cell span
  1535. */
  1536. function jzTDOpen($width = "100", $align = "left", $valign = "top", $class = "", $colspan = "", $widthType = "%"){
  1537. echo ' <td width="'. $width. $widthType. '" align="'. $align. '" valign="'. $valign. '" class="'. $class. '" ';
  1538. if ($colspan <> "0"){
  1539. echo 'colspan="'. $colspan. '"';
  1540. }
  1541. echo '>'. "\n";
  1542. }
  1543. /**
  1544. * Display the opening tag for a table detail
  1545. *
  1546. * @author Ross Carlson
  1547. * @version 04/28/04
  1548. * @since 04/28/04
  1549. */
  1550. function jzTDClose(){
  1551. echo ' </td>'. "\n";
  1552. }
  1553. /**
  1554. * Display an A HREF tag
  1555. *
  1556. * @author Ross Carlson
  1557. * @version 04/28/04
  1558. * @since 04/28/04
  1559. */
  1560. function jzHREF($href, $target = "", $class = "", $onclick = "", $item, $title = ""){
  1561. $retVar = '<a ';
  1562. if ($title <> ""){ $retVar .= 'title="'. $title. '" '; }
  1563. if ($class <> ""){ $retVar .= 'class="'. $class. '" '; }
  1564. if ($target <> ""){ $retVar .= 'target="'. $target. '" '; }
  1565. if ($onclick <> ""){ $retVar .= 'onclick="'. $onclick. '" '; }
  1566. $retVar .= 'href="'. $href. '" >'. $item. '</a>';
  1567. // Now let's display the link
  1568. echo $retVar;
  1569. }
  1570. /**
  1571. * returns the truncated name of an item
  1572. *
  1573. * @author Ross Carlson
  1574. * @version 05/03/04
  1575. * @since 05/03/04
  1576. * @param string $item the item to truncate
  1577. * @param string $length how long should it be?
  1578. */
  1579. function returnItemShortName($item,$length){
  1580. if (strlen($item) > $length + 3){
  1581. return substr($item,0,$length). "...";
  1582. } else {
  1583. return $item;
  1584. }
  1585. }
  1586. /**
  1587. * Hightlights (bolds) part of a string to emphasis it
  1588. *
  1589. * @author Ross Carlson (from www.php.net)
  1590. * @version 01/14/05
  1591. * @since 01/14/05
  1592. * @param string $x The Haystack
  1593. * @param string $var The needle
  1594. * @return string guessed mime type for thie filename
  1595. */
  1596. function highlight($x,$var) {//$x is the string, $var is the text to be highlighted
  1597. if ($var != "") {
  1598. $xtemp = "";
  1599. $i=0;
  1600. while($i<strlen($x)){
  1601. if((($i + strlen($var)) <= strlen($x)) && (strcasecmp($var, substr($x, $i, strlen($var))) == 0)) {
  1602. //this version bolds the text. you can replace the html tags with whatever you like.
  1603. $xtemp .= "<b>" . substr($x, $i , strlen($var)) . "</b>";
  1604. $i += strlen($var);
  1605. }
  1606. else {
  1607. $xtemp .= $x{$i};
  1608. $i++;
  1609. }
  1610. }
  1611. $x = $xtemp;
  1612. }
  1613. return $x;
  1614. }
  1615. /**
  1616. * for php < 4.3.0
  1617. *
  1618. * @author Laurent Perrin
  1619. * @version 02/06/04
  1620. * @since 02/06/04
  1621. * @param string $filename file name
  1622. * @return string guessed mime type for thie filename
  1623. */
  1624. if (!function_exists("mime_content_type")) {
  1625. function mime_content_type($filename) {
  1626. switch(strrchr($filename,'.')){
  1627. case '.mp3':
  1628. case '.mp2':
  1629. case '.mp1':
  1630. return 'audio/mpeg';
  1631. case '.wma':
  1632. return 'audio/wma';
  1633. case '.wav':
  1634. return 'audio/x-wav';
  1635. case '.avi':
  1636. return 'video/x-msvideo';
  1637. case '.qt':
  1638. case '.mov':
  1639. return 'video/quicktime';
  1640. case '.mpe':
  1641. case '.mpg':
  1642. case '.mpeg':
  1643. return 'video/mpeg';;
  1644. } // switch()
  1645. return '';
  1646. }
  1647. }
  1648. /**
  1649. * for php < 4.3.0
  1650. *
  1651. * @author Laurent Perrin
  1652. * @version 02/15/04
  1653. * @since 02/06/04
  1654. * @param string $filename filename
  1655. * @param integer $use_include_path use include path
  1656. * @return string file contents
  1657. */
  1658. if (!function_exists("file_get_contents")) {
  1659. function file_get_contents($filename, $use_include_path = 0) {
  1660. $data = ''; // just to be safe. Dunno, if this is really needed
  1661. $file = @fopen($filename, "rb", $use_include_path);
  1662. if ($file) {
  1663. $data = fread($file, filesize($filename));
  1664. fclose($file);
  1665. }
  1666. return $data;
  1667. }
  1668. }
  1669. /**
  1670. * Updates the track counter for something when it's played
  1671. *
  1672. * @author Ross Carlson
  1673. * @version 07/26/04
  1674. * @version 07/26/04
  1675. * @param string $data the file name to process
  1676. * @return string the file extension (without the .)
  1677. */
  1678. function returnFileExt($data){
  1679. $fileInfo = pathinfo($data);
  1680. if (isset($fileInfo["extension"])){
  1681. return $fileInfo["extension"];
  1682. } else {
  1683. return "";
  1684. }
  1685. }
  1686. /**
  1687. * Handles array sorting for us
  1688. *
  1689. * @author Ross Carlson
  1690. */
  1691. function track_cmp($a, $b){
  1692. if ($a == $b) {
  1693. return 0;
  1694. }
  1695. return ($a > $b) ? -1 : 1;
  1696. }
  1697. /**
  1698. * Returns the difference between 2 microtime stamps
  1699. *
  1700. * @author Ross Carlson
  1701. * @version 06/17/04
  1702. * @since 06/17/04
  1703. * @param string $value What needs to be added to the list
  1704. */
  1705. function microtime_diff($a, $b) {
  1706. list($a_dec, $a_sec) = explode(" ", $a);
  1707. list($b_dec, $b_sec) = explode(" ", $b);
  1708. return $b_sec - $a_sec + $b_dec - $a_dec;
  1709. }
  1710. /**
  1711. * Sets a session variable with the URL of the current page
  1712. *
  1713. * @author Ross Carlson
  1714. * @version 05/04/04
  1715. * @since 05/04/04
  1716. * @returns Session variable $_SESSION['prev_page']
  1717. */
  1718. function setPreviousPage(){
  1719. // Now let's set the session variable for later
  1720. $_SESSION['prev_page'] = @$_SERVER['REQUEST_URI'];
  1721. // Let's make sure it got set right and if not fix it
  1722. if ($_SE

Large files files are truncated, but you can click here to view the full file