JsSlideshow class public methods documentation
  • Class
  • Download

Classes

  • JsSlideshow
   1 <?php
   2 /**
   3 * class JsSlideshow
   4 *
   5 * Used for simple css/html slideshow creation
   6 *
   7 * @package   Main
   8 * @version   0.02
   9 * @since     2015-03-24
  10 *
  11 * @example ../expressiontest.php
  12 * @example ../lifepathtest.php
  13 * @example <br />
  14 *   $slideshow = new JsSlideshow("bg.jpg", 640, 480);<br />
  15 *   $slideshow->addAudio( $audioFile);<br />
  16 *   $slideshow->addSlide( $slideTime );<br />
  17 *   $slideshow->setFontSize( $fontSize );<br />
  18 *   $slideshow->setTitle( $title );<br />
  19 *   $slideshow->addTiles( $fullBirthName ); <br />
  20 *   $slideshowpath = $slideshow->compile();
  21 */
  22 class JsSlideshow
  23 {
  24 
  25     /**
  26     * Array with slides
  27     * @access public
  28     * @var array
  29     */
  30     public $slides = array();
  31 
  32     /**
  33     * Tab width for Bullets in persrnt
  34     * @access public
  35     * @var integer
  36     */
  37     public $tabWidth = 40;
  38 
  39 
  40     /**
  41     * Path to directory with tiles images
  42     * @access private
  43     * @var string
  44     */
  45     private $tilesImagesDirectory = "images";
  46 
  47     /**
  48     * Path where slides to be saved
  49     * @access private
  50     * @var string
  51     */
  52     private $slidesOutputPath = 'slides';
  53 
  54     /**
  55     * Path to ffmpeg executable file
  56     * @access private
  57     * @var string
  58     */
  59     private $ffmpegBinaryPath = "bin/ffmpeg";
  60 
  61     /**
  62     * Array with audio files
  63     * @access protected
  64     * @var array
  65     */
  66     protected $slideshowSounds = array();
  67     
  68     /**
  69     * Array with js scripts
  70     * @access protected
  71     * @var array
  72     */
  73     protected $slideshowScripts = array();
  74 
  75     /**
  76     * Current slide index
  77     * @access protected
  78     * @var integer
  79     */
  80     protected $currentSlideIndex = null;
  81 
  82     /**
  83     * Global slideshow css styles object
  84     * @access protected
  85     * @var stdClass
  86     */
  87     protected $slideshowStyles;
  88 
  89     /**
  90     * Total duration of all audio files in slideshow
  91     * @access protected
  92     * @var float
  93     */
  94     protected $slideshowPlaytime = 0;
  95 
  96     /**
  97     * Total duration of all slides in slideshow
  98     * @access protected
  99     * @var float
 100     */
 101     protected $slideshowSlidesTime = 0;
 102 
 103     /**
 104     * Unique ID of slideshow
 105     * @access protected
 106     * @var string
 107     */
 108     protected $slideshowID;
 109 
 110     /**
 111     * Internal flag that indicates whether to clean "canvas"
 112     * @access protected
 113     * @var boolean
 114     */
 115     protected $clearSlide = false;
 116     
 117 
 118     /**
 119     * Create an instance
 120     *
 121     * @param string  Path to the background image file
 122     * @param integer (optional) Width of slideshow
 123     * @param integer (optional) height of slideshow
 124     * @param string (optional) Unique id of slideshow
 125     *
 126     * @access public
 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     * Sets the tiles images directory
 142     *
 143     * @param string  Path to the tiles images directory
 144     *
 145     * @access public
 146     * @return void
 147     */
 148     public function setTilesImagesDir($path)
 149     {
 150         $this->tilesImagesDirectory = $path;
 151     }
 152 
 153 
 154     /**
 155     * Sets the directory where the slides will be saved
 156     *
 157     * @param string  Path to the slides directory
 158     *
 159     * @access public
 160     * @return void
 161     */
 162     public function setSlidesPath($path)
 163     {
 164         $this->slidesOutputPath = $path;
 165     }
 166 
 167 
 168     /**
 169     * Sets the path to ffmpeg executable file
 170     *
 171     * @param string  Path to the slides directory
 172     *
 173     * @access public
 174     * @return void
 175     */
 176     public function setFfmpegBin($path)
 177     {
 178         $this->ffmpegBinaryPath = $path;
 179     }
 180 
 181 
 182     /**
 183     * Sets the Tab width
 184     *
 185     * @param integer Tab witdth in persent
 186     *
 187     * @access public
 188     * @return void
 189     */
 190     public function setTab($width)
 191     {
 192         $this->tabWidth = $width;
 193     }
 194 
 195     /**
 196     * Get slide object from index or current slide
 197     *
 198     * @param integer Slide index
 199     * @access public
 200     * @return stdClass|boolean Slide object or FALSE
 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     * Get slideshow id
 217     *
 218     * @access public
 219     * @return string
 220     */
 221     public function getID()
 222     {
 223         return $this->slideshowID;
 224     }
 225 
 226     /**
 227     * Adds a slide object to the slideshow
 228     * if no time is specif ied, the slide will be displayed until
 229     * the end of the audio file
 230     *
 231     * @param float Time in seconds
 232     * @access public
 233     * @return JsSlideshow
 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     * Returns the length of the audio file at the specif ied index
 265     * or length of the last audio file is added to the slideshow
 266     * if no index is specif ied
 267     *
 268     * @param integer|null (optional) Index of audio file in slideshow
 269     * @access public
 270     * @return float Lenght of audio file
 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     * Adds a title to the slide
 282     *
 283     * @example $slideshow->setTitle( "Hello there" ); //Simple
 284     * @example $slideshow->setTitle( 'Hello <red>there</red>', ['margin-top'=>'50px'] );
 285     *          //Available all power of CSS markup
 286     *
 287     * @access public
 288     *
 289     * @param string Title text
 290     * @param array (optional) CSS styles
 291     *
 292     * @return JsSlideshow
 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     * Adds a any HTML code to the slide
 311     *
 312     * @example $slideshow->addHTML( '<div class="name"> ... </div>' ); //Simple
 313     * @example $slideshow->addHTML( '<div class="name"> ... </div>', ['margin-top'=>'50px'] );
 314     *          //Available all power of CSS markup
 315     *
 316     * @access public
 317     *
 318     * @param string HTML code
 319     * @param array (optional) CSS styles
 320     *
 321     * @return JsSlideshow
 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     * Adds a javascript callback, which will be called when the slide shown
 339     *
 340     * @example //Call JavascriptFunctionName() in frontend when slide is showing<br />
 341     *          $slideshow->addCallback( 'JavascriptFunctionName' );
 342     *
 343     * @example //Call alert('Hello Alex!') in frontend when slide is showing<br />
 344     *          $slideshow->addCallback( 'alert', ['Hello Alex!'] );
 345     *
 346     * @access public
 347     *
 348     * @param string Callback function name
 349     * @param array (optional) Arguments, which passed to the function
 350     *
 351     * @return JsSlideshow
 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     * Adds a Bullet to the slide
 367     *
 368     * @example $slideshow->addBullet( "Hello there" ); //Simple
 369     * @example $slideshow->addBullet( 'First slide:\tHello <red>there</red>');
 370     *          //Bullet with tab
 371     * @example $slideshow->addBullet( 'Hello <red>there</red>', ['margin-top'=>'50px'] );
 372     *          //Available all power of CSS markup
 373     *
 374     * @access public
 375     *
 376     * @param string Title text
 377     * @param array (optional) CSS styles
 378     *
 379     * @return JsSlideshow
 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     * Adds a Javascript code to the slideshow
 398     *
 399     * @example $slideshow->addJs( 'function x2(val){ return val*2; }' );
 400     *
 401     * @access public
 402     *
 403     * @param string Javascript code
 404     *
 405     * @return JsSlideshow
 406     */
 407     public function addJs($code)
 408     {
 409         $this->slideshowScripts[] = ";".$code;
 410         return $this;
 411     }
 412 
 413 
 414     /**
 415     * Adds a Javascript file to the slideshow
 416     *
 417     * @example $slideshow->addJsFile( 'path/to/javascript/file.js' );
 418     *
 419     * @access public
 420     *
 421     * @param string Path to the Javascript file
 422     *
 423     * @return JsSlideshow
 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     * Adds an image file to the slideshow
 438     *
 439     * @example $slideshow->addImage( 'path/to/the/image.jpg' );
 440     * @example $slideshow->addImage( 'path/to/the/image.jpg',
 441     *                               [ 'border' => 'solid 2 px red' ] );
 442     *
 443     * @access public
 444     *
 445     * @param string Path to the image file
 446     * @param array (optional) CSS styles
 447     *
 448     * @return JsSlideshow
 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     * Adds centered text on a slide
 467     *
 468     * @example $slideshow->addCenteredText( 'Centered text' );
 469     * @example $slideshow->addCenteredText( 'Centered text', [ 'text-shadow' => ' 4px 4px 2px #000' ] ); //With CSS
 470     *
 471     * @access public
 472     *
 473     * @param string Text
 474     * @param array (optional) CSS styles
 475     *
 476     * @return JsSlideshow
 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     * Adds a set of centered text in the slideshow. Each text automatically creates a new slide
 495     *
 496     * @example $slideshow->addCenteredTextSet(
 497     *            [5.000, 'Centered text'],
 498     *            ... ,
 499     *            [null, 'Centered text', ['white-space' => 'nowrap']]
 500     *           );
 501     *
 502     * @access public
 503     *
 504     * @param array,... unlimited arrays in format array(time, text[, style])
 505     *
 506     * @return JsSlideshow
 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     * Adds a set of bullets in the slide. Each bullet placed to the same slide
 522     *
 523     * @example $slideshow->addSlideBullets(
 524     *             [2.000, 'First bullet\t text'],
 525     *             ... ,
 526     *             [ null, 'Last bullet:\t text', ['color' => '#cc00aa']]
 527     *          );
 528     *
 529     * @access public
 530     *
 531     * @param array,... unlimited arrays in format array(time, text[, style])
 532     *
 533     * @return JsSlideshow
 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     * Sets the clearSlide flag to true, which means that the next slide will be cleared
 547     *
 548     * @access public
 549     *
 550     * @return JsSlideshow
 551     */
 552     public function clear()
 553     {
 554         $this->clearSlide = true;
 555         return $this;
 556     }
 557 
 558 
 559 
 560     /**
 561     * Sets the slide font size
 562     *
 563     * @access public
 564     *
 565     * @param ineger Font size
 566     * @param string (optional) Font size units, default - px
 567     *
 568     * @return JsSlideshow
 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     * Adds a audio file to the slideshow
 580     *
 581     * @access public
 582     *
 583     * @param string Path to the audio file
 584     *
 585     * @return JsSlideshow
 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     * Generates an Birth Tiles image and add its to slide
 605     *
 606     * @access public
 607     *
 608     * @param integer Year of birth
 609     * @param integer Month of birth
 610     * @param integer Day of birth
 611     * @param array (optional) CSS styles
 612     *
 613     * @return JsSlideshow
 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     * Generates an Name Tiles image and add its to slide
 755     *
 756     * @access public
 757     *
 758     * @param string Full name
 759     * @param array (optional) CSS styles
 760     *
 761     * @return JsSlideshow
 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     * Compile added slides to JSON scenario, joins audio, joins script and save data to slides directory
 830     *
 831     * @example <br />
 832     *  $slideshow = new JsSlideshow();<br />
 833     *  $slideshow->addAudio($path);<br />
 834     *  $slideshow->addSlide($time);<br />
 835     *  $slideshow->setTitle($title);<br />
 836     *  $slideshowpath = $slideshow->compile();<br />
 837     *
 838     * @access public
 839     *
 840     * @return string Path to the compiled slideshow
 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     * Gets the duration of mp3 file
 868     *
 869     * @access public
 870     * @static
 871     *
 872     * @param string Path to the audio file
 873     *
 874     * @return float Duration in seconds
 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     * Replace scenario tags with HTML tags
 887     *
 888     * @access public
 889     * @static
 890     *
 891     * @param string Text to parse
 892     *
 893     * @return string Result text
 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     * Generate unique id
 908     *
 909     * @access public
 910     * @static
 911     *
 912     * @return string Unique id
 913     */
 914     public static function uniqID()
 915     {
 916         $salt = time();
 917         return md5(session_id().rand()).md5($salt.rand());
 918     }
 919 
 920 
 921     /**
 922     * Joins all slideshow scripts to one file and save it into slideshow directory
 923     *
 924     * @access private
 925     *
 926     * @return string|false Path to the combined js file or FALSE if no scripts added
 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     * Convert slideshow style params to css styles.
 945     *
 946     * @access private
 947     *
 948     * @param stdClass Styles object
 949     *
 950     * @return array CSS styles associative array
 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     * Joins all slideshow audio to one file and save it into slideshow directory.
 973     * That method used ffmpeg to concatenate audio.
 974     *
 975     * @access private
 976     *
 977     * @return string|boolean Path to the combined audio file or FALSE if no scripts added
 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     * Replaces the letters of their numerological values
1006     *
1007     * @access public
1008     * @static
1009     *
1010     * @param string Text to parse
1011     *
1012     * @return string Result text
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     * Replaces letters with umlauts or diactrics their ASCII analogues
1025     *
1026     * @access public
1027     * @static
1028     *
1029     * @param string Text to process
1030     *
1031     * @return string Result text
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     * Returns the char code of the UTF-8 character
1072     * As ord() doesn't work with utf-8, the following function will work well
1073     *
1074     * @access public
1075     * @static
1076     *
1077     * @param string String with character
1078     * @param integer (optional) Reference, as it is not easy to split a utf-8 char-by-char. Useful to iterate on a string
1079     *
1080     * @return integer Char code
1081     */
1082     public static function ordutf8($string, $offset = 0)
1083     {
1084         $code = ord(substr($string, $offset, 1));
1085         if ($code >= 128) {        //otherwise 0xxxxxxx
1086             if ($code < 224) {
1087                 $bytesnumber = 2;                //110xxxxx
1088             } elseif ($code < 240) {
1089                 $bytesnumber = 3;        //1110xxxx
1090             } elseif ($code < 248) {
1091                 $bytesnumber = 4;    //11110xxx
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;        //10xxxxxx
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     * Create GD image from GIF, JPEG or PNG file
1111     *
1112     * @access private
1113     *
1114     * @param string Filename of image file
1115     * @param integer (optional) GD constant with image type. Supported constants: IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG. @see: http://php.net/manual/ru/image.constants.php
1116     *
1117     * @return resource|boolean Returns an image resource identifier on success, FALSE on errors.
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     * Split string with TAB characters
1143     *
1144     * @access private
1145     *
1146     * @param string Text to split
1147     *
1148     * @return string Result text
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     * Places image file to GD image
1164     *
1165     * @access private
1166     *
1167     * @param resource &$canvas GD image to draw $file on it
1168     * @param string Path to the image to be placed on the $canvas
1169     * @param int|string The position on the X axis. If $x equals "center" - $file be placed on horisontally center of $canvas
1170     * @param int|string The position on the Y axis. If $y equals "center" - $file be placed on vertically center of $canvas
1171     *
1172     * @return void
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 
JsSlideshow class public methods documentation API documentation generated by ApiGen 2.8.0