1 <?php
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
22 class JsSlideshow
23 {
24
25 26 27 28 29
30 public $slides = array();
31
32 33 34 35 36
37 public $tabWidth = 40;
38
39
40 41 42 43 44
45 private $tilesImagesDirectory = "images";
46
47 48 49 50 51
52 private $slidesOutputPath = 'slides';
53
54 55 56 57 58
59 private $ffmpegBinaryPath = "bin/ffmpeg";
60
61 62 63 64 65
66 protected $slideshowSounds = array();
67
68 69 70 71 72
73 protected $slideshowScripts = array();
74
75 76 77 78 79
80 protected $currentSlideIndex = null;
81
82 83 84 85 86
87 protected $slideshowStyles;
88
89 90 91 92 93
94 protected $slideshowPlaytime = 0;
95
96 97 98 99 100
101 protected $slideshowSlidesTime = 0;
102
103 104 105 106 107
108 protected $slideshowID;
109
110 111 112 113 114
115 protected $clearSlide = false;
116
117
118 119 120 121 122 123 124 125 126 127
128 public function __construct($backgroundFile, $width = null, $height = null, $id = null)
129 {
130 require_once(dirname(__FILE__)."/getid3/getid3.php");
131
132 $this->slideshowStyles = new stdClass();
133 $this->slideshowStyles->background = $backgroundFile;
134 $this->slideshowStyles->width = $width;
135 $this->slideshowStyles->height = $height;
136 $this->slideshowID = isset($id) ? $id : self::uniqID();
137 }
138
139
140 141 142 143 144 145 146 147
148 public function setTilesImagesDir($path)
149 {
150 $this->tilesImagesDirectory = $path;
151 }
152
153
154 155 156 157 158 159 160 161
162 public function setSlidesPath($path)
163 {
164 $this->slidesOutputPath = $path;
165 }
166
167
168 169 170 171 172 173 174 175
176 public function setFfmpegBin($path)
177 {
178 $this->ffmpegBinaryPath = $path;
179 }
180
181
182 183 184 185 186 187 188 189
190 public function setTab($width)
191 {
192 $this->tabWidth = $width;
193 }
194
195 196 197 198 199 200 201
202 public function get($index = null)
203 {
204 if (!$index) {
205 $index = $this->currentSlideIndex;
206 }
207 if (isset($this->slides[$index])) {
208 $this->currentSlideIndex = $index;
209 return $this->slides[$index];
210 } else {
211 return false;
212 }
213 }
214
215 216 217 218 219 220
221 public function getID()
222 {
223 return $this->slideshowID;
224 }
225
226 227 228 229 230 231 232 233 234
235 public function addSlide($time = null)
236 {
237 if ($this->slideshowPlaytime == 0) {
238 throw new Exception("Add the sound first");
239 }
240
241 if (!isset($time)) {
242 $time = $this->slideshowPlaytime - $this->slideshowSlidesTime;
243 }
244
245 if ($this->slideshowSlidesTime > $this->slideshowPlaytime) {
246 throw new Exception("Slideshow duration more than the duration of the all sounds.
247 Add more sounds or set a shorter duration of the slide");
248 }
249
250 $slide = new stdClass();
251 $slide->clear = $this->clearSlide;
252 $slide->items = array();
253 $slide->time = $time;
254 $slide->css = array();
255 $this->slideshowSlidesTime += $time;
256
257 $this->slides[] = $slide;
258 $this->currentSlideIndex = count($this->slides)-1;
259 $this->clearSlide = false;
260 return $this;
261 }
262
263 264 265 266 267 268 269 270 271
272 public function getAudioLen($index = null)
273 {
274 if (!isset($index)) {
275 $index = count($this->slideshowSounds) - 1;
276 }
277 return isset($this->slideshowSounds[$index]) ? $this->slideshowSounds[$index]['duration'] : 0;
278 }
279
280 281 282 283 284 285 286 287 288 289 290 291 292 293
294 public function setTitle($title, $style = null)
295 {
296 $slide = $this->get($this->currentSlideIndex);
297 $item = array();
298 $item['type'] = 'title';
299 $item['html'] = '<p class="title">'.self::parseTags($title).'</p>';
300 $item['style'] = isset($slide->style['fontSize']) ? array('fontSize'=>$slide->style['fontSize']) : array();
301 if (isset($style) && is_array($style)) {
302 $item['style'] = array_merge($item['style'], $style);
303 }
304 $slide->items[] = $item;
305 return $this;
306 }
307
308
309 310 311 312 313 314 315 316 317 318 319 320 321 322
323 public function addHTML($html, $style = null)
324 {
325 $slide = $this->get($this->currentSlideIndex);
326 $item = array();
327 $item['type'] = 'html';
328 $item['html'] = '<div class="html">'.self::parseTags($title).'</div>';
329 $item['style'] = isset($slide->style['fontSize']) ? array('fontSize'=>$slide->style['fontSize']) : array();
330 if (isset($style) && is_array($style)) {
331 $item['style'] = array_merge($item['style'], $style);
332 }
333 $slide->items[] = $item;
334 return $this;
335 }
336
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
353 public function addCallback($fn, $arguments = array())
354 {
355 $slide = $this->get($this->currentSlideIndex);
356 $item = array();
357 $item['type'] = 'callback';
358 $item['fn'] = $fn;
359 $item['arguments'] = $arguments;
360 $slide->items[] = $item;
361 return $this;
362 }
363
364
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
381 public function addBullet($text, $style = null)
382 {
383 $slide = $this->get($this->currentSlideIndex);
384 $item = array();
385 $item['type'] = 'bullet';
386 $item['html'] = '<p class="bullet">'.$this->prepareTabs(self::parseTags($text)).'</p>';
387 $item['style'] = isset($slide->style['fontSize']) ? array('fontSize'=>$slide->style['fontSize']) : array();
388 if (isset($style) && is_array($style)) {
389 $item['style'] = array_merge($item['style'], $style);
390 }
391 $slide->items[] = $item;
392 return $this;
393 }
394
395
396 397 398 399 400 401 402 403 404 405 406
407 public function addJs($code)
408 {
409 $this->slideshowScripts[] = ";".$code;
410 return $this;
411 }
412
413
414 415 416 417 418 419 420 421 422 423 424
425 public function addJsFile($path)
426 {
427 if (!file_exists($path)) {
428 throw new Exception("Script file not found");
429 }
430
431 $this->slideshowScripts[] = ";".file_get_contents($path);
432 return $this;
433 }
434
435
436 437 438 439 440 441 442 443 444 445 446 447 448 449
450 public function addImage($path, $style = null)
451 {
452 $slide = $this->get($this->currentSlideIndex);
453 $item = array();
454 $item['type'] = 'image';
455 $item['src'] = $path;
456 $item['html'] = '<p class="image"><img src="'.$path.'" /></p>';
457 $item['style'] = isset($slide->style['fontSize']) ? array('fontSize'=>$slide->style['fontSize']) : array();
458 if (isset($style) && is_array($style)) {
459 $item['style'] = array_merge($item['style'], $style);
460 }
461 $slide->items[] = $item;
462 return $this;
463 }
464
465 466 467 468 469 470 471 472 473 474 475 476 477
478 public function addCenteredText($text, $style = null)
479 {
480 $slide = $this->get($this->currentSlideIndex);
481 $item = array();
482 $item['type'] = 'centered';
483 $item['html'] = '<p class="centered">'.self::parseTags($text).'</p>';
484 $item['style'] = isset($slide->style['fontSize']) ? array('fontSize'=>$slide->style['fontSize']) : array();
485 if (isset($style) && is_array($style)) {
486 $item['style'] = array_merge($item['style'], $style);
487 }
488 $slide->items[] = $item;
489 return $this;
490 }
491
492
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
508 public function addCenteredTextSet()
509 {
510 $items = func_get_args();
511 foreach ($items as $item) {
512 $this->clear();
513 $this->addSlide($item[0]);
514 $style = (isset($item[2]) && is_array($item[2])) ? $item[2] : null;
515 $this->addCenteredText($item[1], $style);
516 }
517 return $this;
518 }
519
520 521 522 523 524 525 526 527 528 529 530 531 532 533 534
535 public function addSlideBullets()
536 {
537 $items = func_get_args();
538 foreach ($items as $item) {
539 $this->addSlide($item[0]);
540 $this->addBullet($item[1]);
541 }
542 return $this;
543 }
544
545 546 547 548 549 550 551
552 public function clear()
553 {
554 $this->clearSlide = true;
555 return $this;
556 }
557
558
559
560 561 562 563 564 565 566 567 568 569
570 public function setFontSize($size, $units = null)
571 {
572 $slide = $this->get($this->currentSlideIndex);
573 $slide->css["fontSize"] = $size.($units ? $units : 'px');
574 return $this;
575 }
576
577
578 579 580 581 582 583 584 585 586
587 public function addAudio($path)
588 {
589 if (!file_exists($path)) {
590 throw new Exception("Audio file not found");
591 }
592
593 $duration = self::mp3FileLength($path);
594 $this->slideshowSounds[] = array(
595 'filename'=>$path,
596 'duration'=>$duration
597 );
598 $this->slideshowPlaytime += $duration;
599 return $this;
600 }
601
602
603 604 605 606 607 608 609 610 611 612 613 614
615 public function addBirthTiles($year, $m, $day, $style = null)
616 {
617
618 $months = array(
619 "", "January", "February", "March", "April", "May", "June",
620 "July", "August", "September", "October", "November", "December");
621 $month = $months[$m];
622 $yyyy=0;
623 $mm=0;
624 $dd=0;
625 for ($i=0; $i<4; $i++) {
626 $yyyy += (int)substr($year, $i, 1);
627 }
628
629 $canvas = imagecreatetruecolor($this->slideshowStyles->width-40, 225);
630 imagealphablending($canvas, false);
631 $transparency = imagecolorallocatealpha($canvas, 0, 0, 0, 127);
632 imagefill($canvas, 0, 0, $transparency);
633 imagesavealpha($canvas, true);
634 $canvasWidth = imagesx($canvas);
635 $canvasHeight = imagesy($canvas);
636
637
638 $yy = (strlen($yyyy)>1 && $yyyy!==11 && $yyyy!==22) ? (substr($yyyy, 0, 1)+substr($yyyy, 1, 1)) : $yyyy;
639 $mm = (strlen($m)>1 && $m!=11) ? (substr($m, 0, 1)+substr($m, 1, 1)) : $m;
640 $dd = (strlen($day)>1 && $day!=11 && $day!=22) ? (substr($day, 0, 1)+substr($day, 1, 1)) : $day;
641 $dd = ($dd==10) ? 1 : $dd;
642 $ymd = $yy+$mm+$dd;
643 $offsetX = (strlen($ymd)>1 && $ymd!=11 && $ymd!=22) ? (($canvasWidth/2)-294) : (($canvasWidth/2)-241);
644
645
646
647 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/numbers/start-column/".$year.".png", $offsetX, $canvasHeight - 68);
648 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/numbers/start-column/".intval($day).".png", $offsetX, $canvasHeight - 136);
649 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/numbers/start-column/".$month.".png", $offsetX, $canvasHeight - 204);
650
651 $yearColx2 = 0;
652
653 for ($i=0; $i<4; $i++) {
654 $yearColx2 += (int)substr($year, $i, 1);
655 }
656
657 if (strlen($yearColx2)>1) {
658 $yearColx3 = 0;
659
660 if ($yearColx2==11 || $yearColx2==22) {
661 $yearColx3 = $yearColx2;
662 } else {
663 for ($i=0; $i<2; $i++) {
664 $yearColx3 += (int)substr($yearColx2, $i, 1);
665 }
666 }
667
668 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrow.png", $offsetX+164, $canvasHeight - 68);
669 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/numbers/middle-column/".$yearColx2.".png", $offsetX+222, $canvasHeight - 68);
670 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrow.png", $offsetX+270, $canvasHeight - 68);
671 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/numbers/middle-column/".$yearColx3.".png", $offsetX+328, $canvasHeight - 68);
672 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrowu.png", $offsetX+376, $canvasHeight - 78);
673 } else {
674 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrow2x.png", $offsetX+164, $canvasHeight - 68);
675 $yearColx3 =$yearColx2;
676 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/numbers/middle-column/".$yearColx3.".png", $offsetX+328, $canvasHeight - 68);
677 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrowu.png", $offsetX+376, $canvasHeight - 78);
678 }
679
680 $monthColx3 = 0;
681
682 if (strlen($m)>1 && $m!=11) {
683 $monthColx3 = substr($m, 0, 1) + substr($m, 1, 1);
684
685 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrow.png", $offsetX+164, $canvasHeight - 204);
686 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/numbers/middle-column/".intval($m).".png", $offsetX+222, $canvasHeight - 204);
687 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrow.png", $offsetX+270, $canvasHeight - 204);
688 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/numbers/middle-column/".intval($monthColx3).".png", $offsetX+328, $canvasHeight - 204);
689 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrowd.png", $offsetX+376, $canvasHeight - 194);
690 } else {
691 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrow2x.png", $offsetX+164, $canvasHeight - 204);
692 $monthColx3 = $m;
693 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/numbers/middle-column/".intval($monthColx3).".png", $offsetX+328, $canvasHeight - 204);
694 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrowd.png", $offsetX+376, $canvasHeight - 194);
695 }
696
697 $dayColx2 = 0;
698 $dayColx3 = 0;
699 if (strlen($day)>1 && $day!=11 && $day!=22) {
700 $dayColx2 = substr($day, 0, 1) + substr($day, 1, 1);
701 ;
702
703 if (strlen($dayColx2)>1) {
704 $dayColx3 = substr($dayColx2, 0, 1) + substr($dayColx2, 1, 1);
705
706 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrow.png", $offsetX+164, $canvasHeight - 136);
707 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/numbers/middle-column/".intval($dayColx2).".png", $offsetX+222, $canvasHeight - 136);
708 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrow.png", $offsetX+270, $canvasHeight - 136);
709 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/numbers/middle-column/".intval($dayColx3).".png", $offsetX+328, $canvasHeight - 136);
710 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrow.png", $offsetX+376, $canvasHeight - 136);
711 } else {
712 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrow2x.png", $offsetX+164, $canvasHeight - 136);
713 $dayColx3 = $dayColx2;
714 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/numbers/middle-column/".intval($dayColx3).".png", $offsetX+328, $canvasHeight - 136);
715 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrow.png", $offsetX+376, $canvasHeight - 136);
716 }
717
718
719 } else {
720 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrow2x.png", $offsetX+164, $canvasHeight - 136);
721 $dayColx3 = $day;
722 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/numbers/middle-column/".intval($dayColx3).".png", $offsetX+328, $canvasHeight - 136);
723 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrow.png", $offsetX+376, $canvasHeight - 136);
724 }
725
726 $penultCol = $yearColx3+$monthColx3+$dayColx3;
727 $lastCol = 0;
728
729 if (strlen($penultCol)>1 && $penultCol!==11 && $penultCol!==22) {
730 for ($i=0; $i<2; $i++) {
731 $lastCol += (int)substr($penultCol, $i, 1);
732 }
733
734 $lastCol = (strlen($lastCol)>1) ? substr($lastCol, 0, 1)+substr($lastCol, 1, 1) : $lastCol;
735
736 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/numbers/penult-column/".$penultCol.".png", $offsetX+434, $canvasHeight - 136);
737 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/arrow.png", $offsetX+482, $canvasHeight - 136);
738 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/numbers/last-column/".$lastCol.".png", $offsetX+540, $canvasHeight - 136);
739 } else {
740 $this->drawImageOnCanvas($canvas, $this->tilesImagesDirectory."/numbers/penult-column/".$penultCol.".png", $offsetX+434, $canvasHeight - 136);
741 }
742
743 $output = implode('/', array($this->slidesOutputPath, $this->slideshowID, md5('birthtiles-'.$year.$m.$day).'.png'));
744 if (!file_exists(dirname($output))) {
745 mkdir(dirname($output), 0777, true);
746 }
747 imagepng($canvas, $output, -1);
748 imagedestroy($canvas);
749 return $this->addImage($output, $style);
750 }
751
752
753 754 755 756 757 758 759 760 761 762
763 public function addTiles($text, $style = null)
764 {
765 $leftOffset = 0;
766
767 $vowels = "aeiouyAEIOUY";
768
769 $text = self::normalizeText($text);
770 $tilearr = str_split($text);
771
772 $tile = array();
773 foreach ($tilearr as $k => $char) {
774 $digit = self::toDigit($char);
775 $tile[$k]['char'] = $char;
776 $tile[$k]['digit'] = $digit;
777 $tile[$k]['charCode'] = self::ordutf8($char);
778 $tile[$k]['digitCode'] = self::ordutf8($digit);
779 }
780
781 $letters = count($tile);
782 $maxLetterWidth = floor((($this->slideshowStyles->width-40) - $letters)/$letters);
783
784 if ($maxLetterWidth>=34) {
785 $charWidth = 34;
786 $charHeight = 34;
787 } elseif ($maxLetterWidth<=34 && $maxLetterWidth>=24) {
788 $charWidth = 24;
789 $charHeight = 24;
790 } elseif ($maxLetterWidth<24) {
791 $charWidth = 18;
792 $charHeight = 18;
793 }
794
795 $topOffset = $charHeight+5;
796
797 $canvas = imagecreatetruecolor($this->slideshowStyles->width-40, ($charHeight*3)+10);
798 imagealphablending($canvas, false);
799 $transparency = imagecolorallocatealpha($canvas, 0, 0, 0, 127);
800 imagefill($canvas, 0, 0, $transparency);
801 imagesavealpha($canvas, true);
802 $canvasWidth = imagesx($canvas);
803 $canvasHeight = imagesy($canvas);
804
805
806 foreach ($tile as $key => $char) {
807 $letter = imagecreatefrompng($this->tilesImagesDirectory."/abc/".$charWidth."/".$char['charCode'].".png");
808 $digit = imagecreatefrompng($this->tilesImagesDirectory."/abc/".$charWidth."/".$char['digitCode'].".png");
809
810 $digitOffset = (preg_match("/[aeiouyAEIOUY]/", $char['char'])) ? $topOffset-$charHeight : $topOffset+$charHeight;
811 $left = ($canvasWidth/2)-(($letters*$charWidth)+$letters)/2;
812
813 imagecopy($canvas, $letter, $left+$leftOffset, $topOffset, 0, 0, $charWidth, $charHeight);
814 imagecopy($canvas, $digit, $left+$leftOffset, $digitOffset, 0, 0, $charWidth, $charHeight);
815 $leftOffset += $charWidth+1;
816 }
817
818 $output = implode('/', array($this->slidesOutputPath, $this->slideshowID, md5('tiles-'.$text).'.png'));
819 if (!file_exists(dirname($output))) {
820 mkdir(dirname($output), 0777, true);
821 }
822 imagepng($canvas, $output, -1);
823 imagedestroy($canvas);
824 return $this->addImage($output, $style);
825 }
826
827
828 829 830 831 832 833 834 835 836 837 838 839 840 841
842 public function compile()
843 {
844 $sound = $this->joinAudio();
845 if ($sound === false) {
846 throw new Exception("Unable to join audio");
847 }
848
849 $slideshow = new stdClass();
850 $slideshow->audio = $sound;
851
852 $script = $this->joinScripts();
853 if ($script !== false) {
854 $slideshow->script = $script;
855 }
856
857 $slideshow->playtime = $this->slideshowPlaytime;
858 $slideshow->slides = $this->slides;
859 $slideshow->id = $this->slideshowID;
860 $slideshow->style = $this->processStyle($this->slideshowStyles);
861 file_put_contents(dirname($sound).'/slideshow.json', json_encode($slideshow));
862 return dirname($sound).'/slideshow.json';
863 }
864
865
866 867 868 869 870 871 872 873 874 875
876 public static function mp3FileLength($path)
877 {
878 $ID3 = new getID3();
879 $info = @$ID3->analyze($path);
880 $duration = floatval($info["playtime_seconds"]);
881 return $duration;
882 }
883
884
885 886 887 888 889 890 891 892 893 894
895 public static function parseTags($text)
896 {
897 $text = str_replace(
898 array("<red>", "<b>", "<i>", "</red>", "</b>", "</i>", "\n"),
899 array("<span class=\"red\">", "<strong>", "<em>", "</span>", "</strong>", "</em>", "<br>"),
900 $text
901 );
902 return $text;
903 }
904
905
906 907 908 909 910 911 912 913
914 public static function uniqID()
915 {
916 $salt = time();
917 return md5(session_id().rand()).md5($salt.rand());
918 }
919
920
921 922 923 924 925 926 927
928 private function joinScripts()
929 {
930 if (count($this->slideshowScripts)) {
931 $script = implode("\n;", $this->slideshowScripts);
932 if (class_exists('Minifier')) {
933 $script = Minifier::minify($script);
934 }
935 $output = implode('/', array($this->slidesOutputPath, $this->slideshowID, self::uniqID().'.js'));
936
937 file_put_contents($output, $script);
938 return $output;
939 }
940 return false;
941 }
942
943 944 945 946 947 948 949 950 951
952 private function processStyle($styles)
953 {
954 $_styles = get_object_vars($styles);
955 foreach ($_styles as $name => &$style) {
956 switch ($name) {
957 case 'background':
958 $style = 'url('.$style.')';
959 break;
960 case 'width':
961 case 'height':
962 $style = $style.'px';
963 break;
964 default:
965 break;
966 }
967 }
968 return $_styles;
969 }
970
971 972 973 974 975 976 977 978
979 private function joinAudio()
980 {
981 if (count($this->slideshowSounds)) {
982 $ret = 1;
983 $output = implode('/', array($this->slidesOutputPath, $this->slideshowID, 'sound.mp3'));
984 $sounds = array();
985 foreach ($this->slideshowSounds as $sound) {
986 $sounds[] = $sound['filename'];
987 }
988
989 if (!file_exists(dirname($output))) {
990 mkdir(dirname($output), 0777, true);
991 }
992 if (count($this->slideshowSounds) > 1) {
993 system($this->ffmpegBinaryPath.' -i "concat:'.implode('|', $sounds).'" -map_metadata -1 -vn -c:a copy -f mp3 '.$output.' -y', $ret);
994 } else {
995 system($this->ffmpegBinaryPath.' -i '.$sounds[0].' -vn -c:a copy -f mp3 '.$output.' -y', $ret);
996 }
997
998 return ($ret == 0) ? $output : false;
999 }
1000 return false;
1001 }
1002
1003
1004 1005 1006 1007 1008 1009 1010 1011 1012 1013
1014 public static function toDigit($text)
1015 {
1016 $text = strtolower($text);
1017 $search = str_split('ajsbktcludmvenwfoxgpyhqzir');
1018 $replace = str_split('11122233344455566677788899');
1019 return str_replace($search, $replace, $text);
1020 }
1021
1022
1023 1024 1025 1026 1027 1028 1029 1030 1031 1032
1033 public static function normalizeText($string)
1034 {
1035 $string = htmlentities($string, ENT_QUOTES, 'UTF-8');
1036
1037 $string = preg_replace(
1038 '~&([a-z]{1, 2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i',
1039 '$1',
1040 $string
1041 );
1042
1043 $special = array('À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ð', 'Ñ',
1044 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'ß', 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è',
1045 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'ÿ', 'Ā',
1046 'ā', 'Ă', 'ă', 'Ą', 'ą', 'Ć', 'ć', 'Ĉ', 'ĉ', 'Ċ', 'ċ', 'Č', 'č', 'Ď', 'ď', 'Đ', 'đ', 'Ē', 'ē', 'Ĕ', 'ĕ',
1047 'Ė', 'ė', 'Ę', 'ę', 'Ě', 'ě', 'Ĝ', 'ĝ', 'Ğ', 'ğ', 'Ġ', 'ġ', 'Ģ', 'ģ', 'Ĥ', 'ĥ', 'Ħ', 'ħ', 'Ĩ', 'ĩ', 'Ī',
1048 'ī', 'Ĭ', 'ĭ', 'Į', 'į', 'İ', 'ı', 'IJ', 'ij', 'Ĵ', 'ĵ', 'Ķ', 'ķ', 'Ĺ', 'ĺ', 'Ļ', 'ļ', 'Ľ', 'ľ', 'Ŀ', 'ŀ',
1049 'Ł', 'ł', 'Ń', 'ń', 'Ņ', 'ņ', 'Ň', 'ň', 'ʼn', 'Ō', 'ō', 'Ŏ', 'ŏ', 'Ő', 'ő', 'Œ', 'œ', 'Ŕ', 'ŕ', 'Ŗ', 'ŗ',
1050 'Ř', 'ř', 'Ś', 'ś', 'Ŝ', 'ŝ', 'Ş', 'ş', 'Š', 'š', 'Ţ', 'ţ', 'Ť', 'ť', 'Ŧ', 'ŧ', 'Ũ', 'ũ', 'Ū', 'ū', 'Ŭ',
1051 'ŭ', 'Ů', 'ů', 'Ű', 'ű', 'Ų', 'ų', 'Ŵ', 'ŵ', 'Ŷ', 'ŷ', 'Ÿ', 'Ź', 'ź', 'Ż', 'ż', 'Ž', 'ž', 'ſ', 'ƒ', 'Ơ',
1052 'ơ', 'Ư', 'ư', 'Ǎ', 'ǎ', 'Ǐ', 'ǐ', 'Ǒ', 'ǒ', 'Ǔ', 'ǔ', 'Ǖ', 'ǖ', 'Ǘ', 'ǘ', 'Ǚ', 'ǚ', 'Ǜ', 'ǜ', 'Ǻ', 'ǻ',
1053 'Ǽ', 'ǽ', 'Ǿ', 'ǿ');
1054
1055 $normal = array(
1056 'A', 'A', 'A', 'A', 'A', 'A', 'AE', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', 'D', 'N', 'O', 'O', 'O',
1057 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 's', 'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e',
1058 'i', 'i', 'i', 'i', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'y', 'A', 'a', 'A', 'a',
1059 'A', 'a', 'C', 'c', 'C', 'c', 'C', 'c', 'C', 'c', 'D', 'd', 'D', 'd', 'E', 'e', 'E', 'e', 'E', 'e', 'E',
1060 'e', 'E', 'e', 'G', 'g', 'G', 'g', 'G', 'g', 'G', 'g', 'H', 'h', 'H', 'h', 'I', 'i', 'I', 'i', 'I', 'i',
1061 'I', 'i', 'I', 'i', 'IJ', 'ij', 'J', 'j', 'K', 'k', 'L', 'l', 'L', 'l', 'L', 'l', 'L', 'l', 'l', 'l', 'N',
1062 'n', 'N', 'n', 'N', 'n', 'n', 'O', 'o', 'O', 'o', 'O', 'o', 'OE', 'oe', 'R', 'r', 'R', 'r', 'R', 'r', 'S',
1063 's', 'S', 's', 'S', 's', 'S', 's', 'T', 't', 'T', 't', 'T', 't', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u',
1064 'U', 'u', 'U', 'u', 'W', 'w', 'Y', 'y', 'Y', 'Z', 'z', 'Z', 'z', 'Z', 'z', 's', 'f', 'O', 'o', 'U', 'u',
1065 'A', 'a', 'I', 'i', 'O', 'o', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'A', 'a', 'AE', 'ae', 'O', 'o');
1066
1067 return trim(str_replace($special, $normal, $string));
1068 }
1069
1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081
1082 public static function ordutf8($string, $offset = 0)
1083 {
1084 $code = ord(substr($string, $offset, 1));
1085 if ($code >= 128) {
1086 if ($code < 224) {
1087 $bytesnumber = 2;
1088 } elseif ($code < 240) {
1089 $bytesnumber = 3;
1090 } elseif ($code < 248) {
1091 $bytesnumber = 4;
1092 }
1093 $codetemp = $code - 192 - ($bytesnumber > 2 ? 32 : 0) - ($bytesnumber > 3 ? 16 : 0);
1094 for ($i = 2; $i <= $bytesnumber; $i++) {
1095 $offset ++;
1096 $code2 = ord(substr($string, $offset, 1)) - 128;
1097 $codetemp = $codetemp*64 + $code2;
1098 }
1099 $code = $codetemp;
1100 }
1101 $offset += 1;
1102 if ($offset >= strlen($string)) {
1103 $offset = -1;
1104 }
1105 return $code;
1106 }
1107
1108
1109 1110 1111 1112 1113 1114 1115 1116 1117 1118
1119 private function imagecreatefrom($file, $type = null)
1120 {
1121 if (!$type) {
1122 list($width, $height, $type) = getimagesize($file);
1123 }
1124 switch ($type)
1125 {
1126 case IMAGETYPE_GIF:
1127 return imagecreatefromgif($file);
1128 break;
1129 case IMAGETYPE_JPEG:
1130 return imagecreatefromjpeg($file);
1131 break;
1132 case IMAGETYPE_PNG:
1133 return imagecreatefrompng($file);
1134 break;
1135 default:
1136 throw new Exception('This image type not supported. Currently supported only GIF, JPEG and PNG files.');
1137 break;
1138 }
1139 }
1140
1141 1142 1143 1144 1145 1146 1147 1148 1149
1150 private function prepareTabs($text)
1151 {
1152 if (strpos($text, "\t") !== false) {
1153 $parts = preg_split('/\t/', $text, 2);
1154 return '<span class="left" style="width:'.$this->tabWidth.'%">'.
1155 $parts[0].'</span><span class="right" style="width:'.
1156 (100-$this->tabWidth).'%">'.$parts[1].'</span>';
1157 }
1158 return $text;
1159 }
1160
1161
1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173
1174 private function drawImageOnCanvas(&$canvas, $file, $x = "center", $y = "center")
1175 {
1176 if (is_readable($file)) {
1177 $canvasWidth = imagesx($canvas);
1178 $canvasHeight = imagesy($canvas);
1179
1180 list($width, $height, $type) = getimagesize($file);
1181 $image = $this->imagecreatefrom($file, $type);
1182 if ($image) {
1183 if ($width > $canvasWidth || $height > $canvasHeight) {
1184 $aspect = ceil($width / $height);
1185 if ($width > $height) {
1186 $resized = imagecreatetruecolor($canvasWidth, ceil($canvasWidth/$aspect));
1187 } else {
1188 $resized = imagecreatetruecolor(ceil($canvasHeight*$aspect), $canvasHeight);
1189 }
1190
1191 $resizedWidth = imagesx($resized);
1192 $resizedHeight = imagesy($resized);
1193 imagecopyresampled($resized, $image, 0, 0, 0, 0, $resizedWidth, $resizedHeight, $canvasWidth, $canvasHeight);
1194 $image = $resized;
1195 $width = $resizedWidth;
1196 $height = $resizedHeight;
1197 }
1198
1199 if ($x == "center") {
1200 $x = ceil(($canvasWidth-$width)/2);
1201 }
1202
1203 if ($y == "center") {
1204 $y = ceil(($canvasHeight-$height)/2);
1205 }
1206
1207 imagecopy($canvas, $image, (int)$x, (int)$y, 0, 0, $width, $height);
1208 } else {
1209 throw new Exception("Error processing image");
1210 }
1211 } else {
1212 throw new Exception("Error loading file");
1213 }
1214 }
1215 }
1216