Overview

Packages

  • AlfredBundler
  • None

Classes

  • CocoaDialog
  • ProgressBar
  • TerminalNotifier
  • Overview
  • Package
  • Class
  • Tree
   1: <?php
   2: 
   3: /**
   4:  * PHP API for interacting with OSX dialog spawner CocoaDialog.
   5:  *
   6:  * CocoaDialog is a resource which allows the user to spawn MacOSX aqua dialogs
   7:  * from the command-line. Dialogs are predefined and return input via echo.
   8:  *
   9:  * Official Documentation {@link http://mstratman.github.io/cocoadialog/}
  10:  * LICENSE: GPLv3 {@link https://www.gnu.org/licenses/gpl-3.0.txt}
  11:  *
  12:  * -> Usage
  13:  * ===========================================================================
  14:  *
  15:  * To include this api in your PHP scripts, copy this ``cocoadialog.php`` to
  16:  * a viable place for you to include.
  17:  *
  18:  * Build the CocoaDialog client:
  19:  *
  20:  *     include('cocoadialog');
  21:  *     $client = new CocoaDialog('path to CocoaDialog.app or exec', $debug=Boolean);
  22:  *
  23:  * Now that you have access to the client, you can call specific dialogs:
  24:  *
  25:  *     $my_message_box = $client->msgbox([
  26:  *         'title'=>'My Message Box',
  27:  *         'text'=>'Hello, World!',
  28:  *         'button1'=>'Ok', 'button2'=>'Cancel',
  29:  *         'informative_text'=>'Your information here...',
  30:  *         'icon'=>'home',
  31:  *         'string_output'=>True]);
  32:  *
  33:  *     echo $my_message_box;
  34:  *
  35:  * If the user clicks on the "Ok" button, my_message_box will return ["Ok"]
  36:  * in this script. If, however, the user presses "Cancel", ["Cancel"] will
  37:  * be returned.
  38:  *
  39:  * **NOTE**: The included `debug` parameter is very useful for finding out why
  40:  * your specified parameters are not being shown, or why your parameters are not
  41:  * passing as valid parameters, and thus the dialog is not being spawned.
  42:  *
  43:  * All other dialogs are spawned via similar treatment as shown above.
  44:  * For more info on what parameters are available for a specifc dialog, please
  45:  * visit the `Official Documentation` or play with `debug=True` for a while.
  46:  *
  47:  * To create a progress bar dialog, you have to create a new instance for the
  48:  * progress bar object.
  49:  *
  50:  *     $my_progress_bar = new ProgressBar(
  51:  *         $client,
  52:  *         ['title'=>'My Progress Bar',
  53:  *          'text'=>'Hello, World!',
  54:  *          'percent'=>0,
  55:  *          'icon'=>'info']);
  56:  *
  57:  *     foreach (range(0, 100) as $i) {
  58:  *         $my_progress_bar->update($percent=$i);
  59:  *         time_nanosleep(0, 100000000);
  60:  *     }
  61:  *
  62:  * Whenever the progress bar reaches an EOF, the dialog will kill itself.
  63:  *
  64:  * If you plan to add the `stoppable` feature in your progress bar, you will need
  65:  * to format your loop a little differently.
  66:  *
  67:  *     $my_progress_bar = new ProgressBar(
  68:  *         $client,
  69:  *         ['title'=>'My Progress Bar',
  70:  *          'text'=>'Hello, World!',
  71:  *          'percent'=>0,
  72:  *          'icon'=>'info']);
  73:  *
  74:  *     foreach (range(0, 100) as $i) {
  75:  *         time_nanosleep(0, 100000000);
  76:  *         if ($my_progress_bar->update($percent=$i) == 0) {
  77:  *             break;
  78:  *         }
  79:  *     }
  80:  *
  81:  * The `update` function, returns 1 to signify it is running. When the user stops
  82:  * the progress bar, the `finish` function is called and returns 0 instead.
  83:  *
  84:  *
  85:  * -> Revisions
  86:  * ============================================================================
  87:  * 1.0, 07-28-14: Initial release for (3.0, 0, 'beta')
  88:  *
  89:  * @copyright  Ritashugisha 2014
  90:  * @license    https://www.gnu.org/licenses/gpl-3.0.txt  GPL v3
  91:  * @version    1.0
  92:  */
  93: 
  94: $AUTHOR = 'Ritashugisha <ritashugisha@gmail.com>';
  95: $DATE = '07-28-14';
  96: $VERSION = 1.0;
  97: $COCOA_VERSION = [3.0, 0, 'beta'];
  98: 
  99: if ( ! class_exists( 'CocoaDialog' ) ):
 100: 
 101: /**
 102:  * Main class used for interaction with CocoaDialog.
 103:  *
 104:  * Public class used to initialize the CocoaDialog interaction client.
 105:  * Client inintialization is built by:
 106:  *
 107:  *     $client = new CocoaDialog('path to CocoaDailog.app or exec', $debug=bool)
 108:  *
 109:  * Initializes global options (dict) and global icons (list).
 110:  */
 111: class CocoaDialog {
 112: 
 113:     /**
 114:      * Reference to the CocoaDialog exec.
 115:      * @access private
 116:      * @var string
 117:      */
 118:     private $cocoa;
 119: 
 120:     /**
 121:      * Switch used for logging to the console.
 122:      * @access private
 123:      * @var boolean
 124:      */
 125:     private $debug;
 126: 
 127:     /**
 128:      * Reference to a list of global options.
 129:      * @access private
 130:      * @var array
 131:      */
 132:     private $global_options;
 133: 
 134:     /**
 135:      * Reference to a list of exceptions for key_name lowercase-ing.
 136:      * @access private
 137:      * @var array
 138:      */
 139:     private $lower_exceptions;
 140: 
 141:     /**
 142:      * Reference to a list of global icons.
 143:      * @access private
 144:      * @var array
 145:      */
 146:     public $global_icons;
 147: 
 148: 
 149:     /**
 150:      * This function prints debug logs to the console.
 151:      *
 152:      * @param string $level Logging level (adapted from Python's logging module)
 153:      * @param string $funct Calling function's name
 154:      * @param integer $lineno Calling functions line number
 155:      * @param string $message Desired message
 156:      */
 157:     function log( $level, $funct, $lineno, $message ) {
 158:         if ( $this->debug ) {
 159:             echo sprintf( "[%s] [%s:%d] [%s] %s\xA", date('Y-m-d h:i:s'), basename(__FILE__), $lineno, strtoupper( $level ), $message );
 160:         }
 161:     }
 162: 
 163:     /**
 164:      * CocoaDialog class constructor.
 165:      *
 166:      * @access public
 167:      * @param string $cocoa Path to either CocoaDialog.app or exec
 168:      * @param boolean $debug True if logging is enabled
 169:      */
 170:     public function __construct( $cocoa, $debug=False ) {
 171:         $this->cocoa = $cocoa;
 172:         $this->debug = $debug;
 173:         // Set date/time to avoid warnings/errors.
 174:         if ( ! ini_get( 'date.timezone' ) ) {
 175:           $tz = exec( 'tz=`ls -l /etc/localtime` && echo ${tz#*/zoneinfo/}' );
 176:           ini_set( 'date.timezone', $tz );
 177:         }
 178:         if ( file_exists( $this->cocoa ) ) {
 179:             if ( 'app' === strtolower( pathinfo( $cocoa, PATHINFO_EXTENSION ) ) ) {
 180:                 $this->cocoa = '/' . join( '/', array( trim( $cocoa, '/' ), trim( '/Contents/MacOS/cocoadialog', '/' ) ) );
 181:                 $valid_cocoa = file_exists( $this->cocoa );
 182:             }
 183:             else {
 184:                 $valid_cocoa = ( strtolower( basename( $this->cocoa ) ) === 'cocoadialog' );
 185:             }
 186:         }
 187:         else {
 188:             $valid_cocoa = False;
 189:         }
 190:         if ( ! $valid_cocoa ) {
 191:             $this->log( 'critical', __FUNCTION__, __LINE__, sprintf( 'invalid path to cocoadialog (%s)', $this->cocoa ) );
 192:             die();
 193:         }
 194:         $this->global_options = [
 195:             'title' => ['string'],
 196:             'string_output' => ['boolean'],
 197:             'no_newline' => ['boolean'],
 198:             'width' => ['integer', 'double'],
 199:             'height' => ['integer', 'double'],
 200:             'posX' => ['integer', 'double'],
 201:             'posY' => ['integer', 'double'],
 202:             'timeout' => ['integer', 'double'],
 203:             'timeout_format' => ['string'],
 204:             'icon' => ['string'],
 205:             'icon_bundle' => ['string'],
 206:             'icon_file' => ['string'],
 207:             'icon_size' => ['integer'],
 208:             'icon_height' => ['integer'],
 209:             'icon_width' => ['integer'],
 210:             'icon_type' => ['string'], // Broken option
 211:             'debug' => ['boolean'],
 212:             'help' => ['boolean']
 213:         ];
 214:         $this->lower_exceptions = ['posX', 'posY'];
 215:         $this->global_icons = [
 216:             'addressbook', 'airport', 'airport2', 'application', 'archive', 'bluetooth', 'bonjour', 'atom', 'burn', 'hazard', 'caution', 'cd',
 217:             'cocoadialog', 'computer', 'dashboard', 'dock', 'document', 'documents', 'download', 'eject', 'everyone', 'executable',
 218:             'favorite', 'heart', 'fileserver', 'filevault', 'finder', 'firewire', 'folder', 'folderopen', 'foldersmart', 'gear',
 219:             'general', 'globe', 'group', 'help', 'home', 'info', 'installer', 'ipod', 'movie', 'music', 'network', 'notice', 'package',
 220:             'preferences', 'printer', 'screenshare', 'search', 'find', 'security', 'sound', 'stop', 'x', 'sync', 'trash', 'trashfull',
 221:             'update', 'url', 'usb', 'user', 'person', 'utilities', 'widget'
 222:         ];
 223:     }
 224: 
 225:     public function _format_passed( $passed ) {
 226:         $new_passed = [];
 227:         foreach ($passed as $k => $v) {
 228:             if ( ! ( in_array( $k, $this->lower_exceptions ) ) ) {
 229:                 $new_passed[strtolower( $k )] = $v;
 230:             }
 231:             else {
 232:                 $new_passed[$k] = $v;
 233:             }
 234:         }
 235:         return $new_passed;
 236:     }
 237: 
 238:     public function _format_notify( $passed ) {
 239: 
 240:         // Cleanup for passed hexadecimal colors. CocoaDialog only accepts
 241:         // numbers (xxx or xxxxxx), so just in case users get crazy, we will
 242:         // regrex it.
 243:         $valid_x_placement = ['center', 'left', 'right'];
 244:         $valid_y_placement = ['center', 'top', 'bottom'];
 245:         foreach (['text_color', 'border_color', 'background_top', 'background_bottom'] as $i) {
 246:             if ( in_array( $i, array_keys( $passed ) ) ) {
 247:                 preg_match( "/^(.*?)(?P<hex>([0-9a-fA-F]{3}){1,2})$/", $passed[$i], $group );
 248:                 if ( $group['hex'] ) {
 249:                     $passed[$i] = $group['hex'];
 250:                 }
 251:                 else {
 252:                     $this->log('warning', __FUNCTION__, __LINE__,
 253:                         sprintf('removing invalid (%s), got (%s), expected (#XXX or #XXXXXX)',
 254:                             $i, $passed[$i]));
 255:                     unset($passed[$i]);
 256:                 }
 257:             }
 258:         }
 259: 
 260:         // Cleanup/validation for x_placement and y_placement
 261:         foreach ([['x_placement', $valid_x_placement], ['y_placement', $valid_y_placement]] as $i) {
 262:             if ( in_array($i[0], array_keys( $passed ) ) && !( in_array( $passed[$i[0]], $i[1] ) ) ) {
 263:                 $this->log('warning', __FUNCTION__, __LINE__,
 264:                     sprintf('removing invalid (%s), got (%s), expected (%s)',
 265:                         $i[0], $passed[$i[0]], implode(' or ', $i[1])));
 266:                 unset($passed[$i[0]]);
 267:             }
 268:         }
 269:         return $passed;
 270:     }
 271: 
 272:     /**
 273:      * Run a process on the host system.
 274:      *
 275:      * @param string $process Process to be run
 276:      * @return string Output of process
 277:      */
 278:     public function _run_subprocess( $process ) {
 279:         // Preferrably, we should send a string rather than a list in PHP
 280:         if ( gettype( $process ) === 'array' ) {
 281:             $process = join( ' ', $process );
 282:         }
 283:         return shell_exec( $process );
 284:     }
 285: 
 286:     /**
 287:      * Validate and clean up passed dialog options.
 288:      *
 289:      * @param array $passed Associative array of passed dialog arguemnts
 290:      * @param array $custom_options Associative array of calling dialog's unique arguments
 291:      * @return boolean True if OK for dialog to be shown
 292:      */
 293:     public function _valid_options( $passed, $custom_options ) {
 294: 
 295:         $_is_valid = True;
 296: 
 297:         // Join the valid options with the global options into a single associative array
 298:         // and grab the function name
 299:         $valid_passed = array_merge( $custom_options['custom_options'], $this->global_options );
 300:         $_funct = $custom_options['dialog_name'];
 301: 
 302:         // First, check that all passed options are valid and have a valid corresponding type.
 303:         foreach ( array_keys( $passed ) as $passed_key ) {
 304:             if ( in_array( $passed_key, array_keys( $valid_passed ) ) ) {
 305:                 if ( ! in_array( gettype( $passed[$passed_key] ), $valid_passed[$passed_key] ) ) {
 306:                     $this->log( 'warning', __FUNCTION__, __LINE__,
 307:                         sprintf( 'removing (%s) invalid type, expected (%s), got (%s)',
 308:                             $passed_key,
 309:                             implode( ' or ', array_values( $valid_passed[$passed_key] ) ),
 310:                             gettype( $passed[$passed_key] ) ) );
 311:                     unset( $passed[$passed_key] );
 312:                 }
 313:             }
 314:             else {
 315:                 $this->log( 'warning', __FUNCTION__, __LINE__,
 316:                     sprintf( 'removing (%s) invalid parameter, available are (%s)',
 317:                         $passed_key,
 318:                         implode( ', ', array_keys( $valid_passed ) ) ) );
 319:                 unset( $passed[$passed_key] );
 320:             }
 321:         }
 322: 
 323:         // Next, check that passed options contain the required options.
 324:         foreach ( $custom_options['required_options'] as $required_key ) {
 325:             if ( in_array( $required_key, array_keys( $passed ) ) ) {
 326:                 foreach ( ['items', 'with_extensions', 'checked', 'disabled'] as $_lists ) {
 327:                     if ( $_lists === strtolower( $required_key ) ) {
 328:                        if ( count( $passed[$_lists] ) <= 0) {
 329:                             $this->log('error', __FUNCTION__, __LINE__, 'length of items must be > 0');
 330:                             $_is_valid = False;
 331:                         }
 332:                     }
 333:                 }
 334:             }
 335:             else {
 336:                 $this->log( 'error', __FUNCTION__, __LINE__,
 337:                     sprintf( 'missing required parameter (%s)',
 338:                         $required_key ) );
 339:                 $_is_valid = False;
 340:             }
 341:         }
 342: 
 343:         // Finally, check that (if icon is passed), it is a valid icon in CocoaDialog.
 344:         if ( in_array( 'icon', array_keys( $passed ) ) ) {
 345:             if ( ! in_array( $passed['icon'], $this->global_icons ) ) {
 346:                 $this->log( 'warning', __FUNCTION__, __LINE__,
 347:                     sprintf( 'removing invalid icon (%s), available are (%s)',
 348:                         $passed['icon'],
 349:                         implode( ', ', $this->global_icons ) ) );
 350:                 unset( $passed['icon'] );
 351:             }
 352:         }
 353: 
 354:         // PHP is stupid, that's why we have to remember and return the formated passed
 355:         // arguments back to our dialog
 356:         return [$_is_valid, $passed];
 357:     }
 358: 
 359:     /**
 360:      * Display the passed dialog after some crutial formatting.
 361:      *
 362:      * @param string $funct Dialog name
 363:      * @param array $passed Associative array of passed dialog options
 364:      * @param boolean $return_process True if return process array instead of display
 365:      * @return string Output of dialog
 366:      */
 367:     public function _display( $funct, $passed, $return_process=False ) {
 368:         foreach ( $passed as $k => $v ) {
 369:             $passed[sprintf( '--%s', str_replace( '_', '-', $k ) )] = $passed[$k];
 370:             unset($passed[$k]);
 371:         }
 372:         $process = ["'$this->cocoa'", str_replace( '_', '-', $funct )];
 373:         foreach ( $passed as $k => $v ) {
 374:             if ( 'string' === gettype( $v ) || 'integer' === gettype( $v ) ||
 375:                 'float' === gettype( $v ) || ( 'array' === gettype( $v ) && count( $v ) > 0 ) ) {
 376:                 array_push( $process, $k );
 377:                 if ( 'array' === gettype( $v ) ) {
 378:                     foreach ( $v as $i ) {
 379:                         array_push( $process, sprintf( '"%s"', $i ) );
 380:                     }
 381:                 }
 382:                 else {
 383:                     array_push( $process, sprintf( '"%s"', strval( $v ) ) );
 384:                 }
 385:             }
 386:             else {
 387:                 if ( ( 'boolean' === gettype( $v ) ) && $v ) {
 388:                     array_push( $process, $k );
 389:                 }
 390:             }
 391:         }
 392:         if ( ! $return_process ) {
 393:             try {
 394:                 $this->log('info', __FUNCTION__, __LINE__, implode( ' ', $process ) );
 395:                 $dialog = explode( "\n", $this->_run_subprocess( implode( ' ', $process ) ) );
 396:                 unset( $dialog[count($dialog) - 1] );
 397:                 return $dialog;
 398:             } catch ( Exception $e ) {
 399:                 $this->log( 'critical', __FUNCTION__, __LINE__, $e );
 400:             }
 401:         }
 402:         else {
 403:             return $process;
 404:         }
 405:     }
 406: 
 407:     /**
 408:      * Dialog type bubble
 409:      *
 410:      * Valid parameters are listed at:
 411:      * <http://mstratman.github.io/cocoadialog/#documentation3.0/bubble_control>
 412:      *
 413:      * @param array $_passed Dialog paramenters
 414:      * @return string Output from dialog
 415:      */
 416:     public function bubble(array $_passed) {
 417:         $custom_options = [
 418:             'no_timeout' => ['bool'],
 419:             'alpha' => ['integer', 'double'],
 420:             'x_placement' => ['string'],
 421:             'y_placement' => ['string'],
 422:             'text' => ['string'],
 423:             'text_color' => ['string'],
 424:             'border_color' => ['string'],
 425:             'background_top' => ['string'],
 426:             'background_bottom' => ['string']
 427:         ];
 428:         $custom_options = [
 429:             'dialog_name' => __FUNCTION__,
 430:             'required_options' => ['title', 'text'],
 431:             'custom_options' => $custom_options
 432:         ];
 433:         $_passed = $this->_format_passed( $_passed );
 434:         $_valid = $this->_valid_options( $_passed, $custom_options );
 435:         if ( $_valid[0] ) {
 436:             $_valid[1] = $this->_format_passed( $_valid[1] );
 437:             $this->_display( __FUNCTION__, $_valid[1] );
 438:         }
 439:     }
 440: 
 441:     /**
 442:      * Dialog type notify
 443:      *
 444:      * @param array $_passed Dialog paramenters
 445:      * @return string Output from dialog
 446:      */
 447:     public function notify(array $_passed) {
 448:         $custom_options = [
 449:             'description' => ['string'],
 450:             'sticky' => ['boolean'],
 451:             'no_growl' => ['boolean'],
 452:             'alpha' => ['integer', 'double'],
 453:             'x_placement' => ['string'],
 454:             'y_placement' => ['string'],
 455:             'text_color' => ['string'],
 456:             'border_color' => ['string'],
 457:             'background_top' => ['string'],
 458:             'background_bottom' => ['string'],
 459:             'fh' => ['boolean'], // Unknown options
 460:         ];
 461:         $custom_options = [
 462:             'dialog_name' => __FUNCTION__,
 463:             'required_options' => ['title', 'description'],
 464:             'custom_options' => $custom_options
 465:         ];
 466:         $_passed = $this->_format_passed( $_passed );
 467:         $_valid = $this->_valid_options( $_passed, $custom_options );
 468:         if ( $_valid[0] ) {
 469:             $_valid[1] = $this->_format_passed( $_valid[1] );
 470:             $this->_display( __FUNCTION__, $_valid[1] );
 471:         }
 472:     }
 473: 
 474:     /**
 475:      * Dialog type checkbox
 476:      *
 477:      * @param array $_passed Dialog paramenters
 478:      * @return string Output from dialog
 479:      */
 480:     public function checkbox(array $_passed) {
 481:         $custom_options = [
 482:             'label' => ['string'],
 483:             'checked' => ['array'],
 484:             'columns' => ['integer'],
 485:             'rows' => ['integer'],
 486:             'disabled' => ['array'],
 487:             'items' => ['array'],
 488:             'button1' => ['string'],
 489:             'button2' => ['string'],
 490:             'button3' => ['string'],
 491:         ];
 492:         $custom_options = [
 493:             'dialog_name' => __FUNCTION__,
 494:             'required_options' => ['button1', 'items'],
 495:             'custom_options' => $custom_options
 496:         ];
 497:         $_passed = $this->_format_passed( $_passed );
 498:         $_valid = $this->_valid_options( $_passed, $custom_options );
 499:         if ( $_valid[0] ) {
 500:             return $this->_display( __FUNCTION__, $_valid[1] );
 501:         }
 502:     }
 503: 
 504:     /**
 505:      * Dialog type radio
 506:      *
 507:      * @param array $_passed Dialog paramenters
 508:      * @return string Output from dialog
 509:      */
 510:     public function radio(array $_passed) {
 511:         $custom_options = [
 512:             'label' => ['string'],
 513:             'selected' => ['integer'],
 514:             'columns' => ['integer'],
 515:             'rows' => ['integer'],
 516:             'disabled' => ['array'],
 517:             'items' => ['array'],
 518:             'button1' => ['string'],
 519:             'button2' => ['string'],
 520:             'button3' => ['string'],
 521:         ];
 522:         $custom_options = [
 523:             'dialog_name' => __FUNCTION__,
 524:             'required_options' => ['button1', 'items'],
 525:             'custom_options' => $custom_options
 526:         ];
 527:         $_passed = $this->_format_passed( $_passed );
 528:         $_valid = $this->_valid_options( $_passed, $custom_options );
 529:         if ( $_valid[0] ) {
 530:             return $this->_display( __FUNCTION__, $_valid[1] );
 531:         }
 532:     }
 533: 
 534:     /**
 535:      * Dialog type slider
 536:      *
 537:      * @param array $_passed Dialog paramenters
 538:      * @return string Output from dialog
 539:      */
 540:     public function slider(array $_passed) {
 541:         $custom_options = [
 542:             'label' => ['string'],
 543:             'always_show_value' => ['boolean'],
 544:             'min' => ['integer', 'double'],
 545:             'max' => ['integer', 'double'],
 546:             'ticks' => ['integer', 'double'],
 547:             'slider_label' => ['string'],
 548:             'value' => ['integer', 'double'],
 549:             'button1' => ['string'],
 550:             'button2' => ['string'],
 551:             'button3' => ['string'],
 552:             'return_float' => ['boolean'],
 553:         ];
 554:         $custom_options = [
 555:             'dialog_name' => __FUNCTION__,
 556:             'required_options' => ['button1', 'min', 'max'],
 557:             'custom_options' => $custom_options
 558:         ];
 559:         $_passed = $this->_format_passed( $_passed );
 560:         $_valid = $this->_valid_options( $_passed, $custom_options );
 561:         if ( $_valid[0] ) {
 562:             return $this->_display( __FUNCTION__, $_valid[1] );
 563:         }
 564:     }
 565: 
 566:     /**
 567:      * Dialog type msgbox
 568:      *
 569:      * Valid parameters are listed at:
 570:      * <http://mstratman.github.io/cocoadialog/#documentation3.0/msgbox_control>
 571:      *
 572:      * @param array $_passed Dialog paramenters
 573:      * @return string Output from dialog
 574:      */
 575:     public function msgbox(array $_passed) {
 576:         $custom_options = [
 577:             'text' => ['string'],
 578:             'informative_text' => ['string'],
 579:             'button1' => ['string'],
 580:             'button2' => ['string'],
 581:             'button3' => ['string'],
 582:             'no_cancel' => ['boolean'],
 583:             'float' => ['boolean'],
 584:         ];
 585:         $custom_options = [
 586:             'dialog_name' => __FUNCTION__,
 587:             'required_options' => ['button1'],
 588:             'custom_options' => $custom_options
 589:         ];
 590:         $_passed = $this->_format_passed( $_passed );
 591:         $_valid = $this->_valid_options( $_passed, $custom_options );
 592:         if ( $_valid[0] ) {
 593:             return $this->_display( __FUNCTION__, $_valid[1] );
 594:         }
 595:     }
 596: 
 597:     /**
 598:      * Dialog type ok_msgbox
 599:      *
 600:      * Valid parameters are listed at:
 601:      * <http://mstratman.github.io/cocoadialog/#documentation3.0/ok-msgbox_control>
 602:      *
 603:      * @param array $_passed Dialog paramenters
 604:      * @return string Output from dialog
 605:      */
 606:     public function ok_msgbox(array $_passed) {
 607:         $custom_options = [
 608:             'text' => ['string'],
 609:             'informative_text' => ['string'],
 610:             'no_cancel' => ['boolean'],
 611:             'float' => ['boolean'],
 612:         ];
 613:         $custom_options = [
 614:             'dialog_name' => __FUNCTION__,
 615:             'required_options' => [],
 616:             'custom_options' => $custom_options
 617:         ];
 618:         $_passed = $this->_format_passed( $_passed );
 619:         $_valid = $this->_valid_options( $_passed, $custom_options );
 620:         if ( $_valid[0] ) {
 621:             return $this->_display( __FUNCTION__, $_valid[1] );
 622:         }
 623:     }
 624: 
 625:     /**
 626:      * Dialog type yesno_msgbox
 627:      *
 628:      * Valid parameters are listed at:
 629:      * <http://mstratman.github.io/cocoadialog/#documentation3.0/yesno-msgbox_control>
 630:      *
 631:      * @param array $_passed Dialog paramenters
 632:      * @return string Output from dialog
 633:      */
 634:     public function yesno_msgbox(array $_passed) {
 635:         $custom_options = [
 636:             'text' => ['string'],
 637:             'informative_text' => ['string'],
 638:             'no_cancel' => ['boolean'],
 639:             'float' => ['boolean'],
 640:         ];
 641:         $custom_options = [
 642:             'dialog_name' => __FUNCTION__,
 643:             'required_options' => [],
 644:             'custom_options' => $custom_options
 645:         ];
 646:         $_passed = $this->_format_passed( $_passed );
 647:         $_valid = $this->_valid_options( $_passed, $custom_options );
 648:         if ( $_valid[0] ) {
 649:             return $this->_display( __FUNCTION__, $_valid[1] );
 650:         }
 651:     }
 652: 
 653:     /**
 654:      * Dialog type inputbox
 655:      *
 656:      * Valid parameters are listed at:
 657:      * <http://mstratman.github.io/cocoadialog/#documentation3.0/inputbox_control>
 658:      *
 659:      * @param array $_passed Dialog paramenters
 660:      * @return string Output from dialog
 661:      */
 662:     public function inputbox(array $_passed) {
 663:         $custom_options = [
 664:             'text' => ['string'],
 665:             'informative_text' => ['string'],
 666:             'button1' => ['string'],
 667:             'button2' => ['string'],
 668:             'button3' => ['string'],
 669:             'no_cancel' => ['boolean'],
 670:             'float' => ['boolean'],
 671:             'no_show' => ['boolean']
 672:         ];
 673:         $custom_options = [
 674:             'dialog_name' => __FUNCTION__,
 675:             'required_options' => [],
 676:             'custom_options' => $custom_options
 677:         ];
 678:         $_passed = $this->_format_passed( $_passed );
 679:         $_valid = $this->_valid_options( $_passed, $custom_options );
 680:         if ( $_valid[0] ) {
 681:             return $this->_display( __FUNCTION__, $_valid[1] );
 682:         }
 683:     }
 684: 
 685:     /**
 686:      * Dialog type standard_inputbox
 687:      *
 688:      * Valid parameters are listed at:
 689:      * <http://mstratman.github.io/cocoadialog/#documentation3.0/standard-box_control>
 690:      *
 691:      * @param array $_passed Dialog paramenters
 692:      * @return string Output from dialog
 693:      */
 694:     public function standard_inputbox(array $_passed) {
 695:         $custom_options = [
 696:             'text' => ['string'],
 697:             'informative_text' => ['string'],
 698:             'no_cancel' => ['boolean'],
 699:             'float' => ['boolean'],
 700:             'no_show' => ['boolean']
 701:         ];
 702:         $custom_options = [
 703:             'dialog_name' => __FUNCTION__,
 704:             'required_options' => [],
 705:             'custom_options' => $custom_options
 706:         ];
 707:         $_passed = $this->_format_passed( $_passed );
 708:         $_valid = $this->_valid_options( $_passed, $custom_options );
 709:         if ( $_valid[0] ) {
 710:             return $this->_display( __FUNCTION__, $_valid[1] );
 711:         }
 712:     }
 713: 
 714:     /**
 715:      * Dialog type secure_inputbox
 716:      *
 717:      * Valid parameters are listed at:
 718:      * <http://mstratman.github.io/cocoadialog/#documentation3.0/secure-inputbox_control>
 719:      *
 720:      * @param array $_passed Dialog paramenters
 721:      * @return string Output from dialog
 722:      */
 723:     public function secure_inputbox(array $_passed) {
 724:         $custom_options = [
 725:             'text' => ['string'],
 726:             'informative_text' => ['string'],
 727:             'button1' => ['string'],
 728:             'button2' => ['string'],
 729:             'button3' => ['string'],
 730:             'no_cancel' => ['boolean'],
 731:             'float' => ['boolean'],
 732:         ];
 733:         $custom_options = [
 734:             'dialog_name' => __FUNCTION__,
 735:             'required_options' => [],
 736:             'custom_options' => $custom_options
 737:         ];
 738:         $_passed = $this->_format_passed( $_passed );
 739:         $_valid = $this->_valid_options( $_passed, $custom_options );
 740:         if ( $_valid[0] ) {
 741:             return $this->_display( __FUNCTION__, $_valid[1] );
 742:         }
 743:     }
 744: 
 745:     /**
 746:      * Dialog type secure_standard_inputbox
 747:      *
 748:      * Valid parameters are listed at:
 749:      * <http://mstratman.github.io/cocoadialog/#documentation3.0/secure-standard-inputbox_control>
 750:      *
 751:      * @param array $_passed Dialog paramenters
 752:      * @return string Output from dialog
 753:      */
 754:     public function secure_standard_inputbox(array $_passed) {
 755:         $custom_options = [
 756:             'text' => ['string'],
 757:             'informative_text' => ['string'],
 758:             'no_cancel' => ['boolean'],
 759:             'float' => ['boolean'],
 760:         ];
 761:         $custom_options = [
 762:             'dialog_name' => __FUNCTION__,
 763:             'required_options' => [],
 764:             'custom_options' => $custom_options
 765:         ];
 766:         $_passed = $this->_format_passed( $_passed );
 767:         $_valid = $this->_valid_options( $_passed, $custom_options );
 768:         if ( $_valid[0] ) {
 769:             return $this->_display( __FUNCTION__, $_valid[1] );
 770:         }
 771:     }
 772: 
 773:     /**
 774:      * Dialog type fileselect
 775:      *
 776:      * Valid parameters are listed at:
 777:      * <http://mstratman.github.io/cocoadialog/#documentation3.0/fileselect_control>
 778:      *
 779:      * @param array $_passed Dialog paramenters
 780:      * @return string Output from dialog
 781:      */
 782:     public function fileselect(array $_passed) {
 783:         $custom_options = [
 784:             'text' => ['string'],
 785:             'select_directories' => ['boolean'],
 786:             'select_only_directories' => ['boolean'],
 787:             'packages_as_directories' => ['boolean'],
 788:             'select_multiple' => ['boolean'],
 789:             'with_extensions' => ['array'],
 790:             'with_directory' => ['string'],
 791:             'with_file' => ['string']
 792:         ];
 793:         $custom_options = [
 794:             'dialog_name' => __FUNCTION__,
 795:             'required_options' => [],
 796:             'custom_options' => $custom_options
 797:         ];
 798:         $_passed = $this->_format_passed( $_passed );
 799:         $_valid = $this->_valid_options( $_passed, $custom_options );
 800:         if ( $_valid[0] ) {
 801:             return $this->_display( __FUNCTION__, $_valid[1] );
 802:         }
 803:     }
 804: 
 805:     /**
 806:      * Dialog type fileselect
 807:      *
 808:      * Valid parameters are listed at:
 809:      * <http://mstratman.github.io/cocoadialog/#documentation3.0/fileselect_control>
 810:      *
 811:      * @param array $_passed Dialog paramenters
 812:      * @return string Output from dialog
 813:      */
 814:     public function filesave(array $_passed) {
 815:         $custom_options = [
 816:             'text' => ['string'],
 817:             'packages_as_directories' => ['boolean'],
 818:             'no_create_directories' => ['boolean'],
 819:             'with_extensions' => ['array'],
 820:             'with_directory' => ['string'],
 821:             'with_file' => ['string']
 822:         ];
 823:         $custom_options = [
 824:             'dialog_name' => __FUNCTION__,
 825:             'required_options' => [],
 826:             'custom_options' => $custom_options
 827:         ];
 828:         $_passed = $this->_format_passed( $_passed );
 829:         $_valid = $this->_valid_options( $_passed, $custom_options );
 830:         if ( $_valid[0] ) {
 831:             return $this->_display( __FUNCTION__, $_valid[1] );
 832:         }
 833:     }
 834: 
 835:     /**
 836:      * Dialog type textbox
 837:      *
 838:      * Valid parameters are listed at:
 839:      * <http://mstratman.github.io/cocoadialog/#documentation3.0/textbox_control>
 840:      *
 841:      * @param array $_passed Dialog paramenters
 842:      * @return string Output from dialog
 843:      */
 844:     public function textbox(array $_passed) {
 845:         $custom_options = [
 846:             'text' => ['string'],
 847:             'text_from_file' => ['string'],
 848:             'informative_text' => ['string'],
 849:             'button1' => ['string'],
 850:             'button2' => ['string'],
 851:             'button3' => ['string'],
 852:             'editable' => ['boolean'],
 853:             'focus_textbox' => ['boolean'],
 854:             'selected' => ['boolean'],
 855:             'scroll_to' => ['string'],
 856:             'float' => ['boolean'],
 857:         ];
 858:         $custom_options = [
 859:             'dialog_name' => __FUNCTION__,
 860:             'required_options' => [],
 861:             'custom_options' => $custom_options
 862:         ];
 863:         $_passed = $this->_format_passed( $_passed );
 864:         $_valid = $this->_valid_options( $_passed, $custom_options );
 865:         if ( $_valid[0] ) {
 866:             return $this->_display( __FUNCTION__, $_valid[1] );
 867:         }
 868:     }
 869: 
 870:     /**
 871:      * Dialog type dropdown
 872:      *
 873:      * Valid parameters are listed at:
 874:      * <http://mstratman.github.io/cocoadialog/#documentation3.0/dropdown_control>
 875:      *
 876:      * @param array $_passed Dialog paramenters
 877:      * @return string Output from dialog
 878:      */
 879:     public function dropdown(array $_passed) {
 880:         $custom_options = [
 881:             'text' => ['string'],
 882:             'items' => ['array'],
 883:             'pulldown' => ['boolean'],
 884:             'button1' => ['string'],
 885:             'button2' => ['string'],
 886:             'button3' => ['string'],
 887:             'exit_onchange' => ['boolean'],
 888:             'float' => ['boolean'],
 889:         ];
 890:         $custom_options = [
 891:             'dialog_name' => __FUNCTION__,
 892:             'required_options' => [],
 893:             'custom_options' => $custom_options
 894:         ];
 895:         $_passed = $this->_format_passed( $_passed );
 896:         $_valid = $this->_valid_options( $_passed, $custom_options );
 897:         if ( $_valid[0] ) {
 898:             return $this->_display( __FUNCTION__, $_valid[1] );
 899:         }
 900:     }
 901: 
 902:     /**
 903:      * Dialog type standard_dropdown
 904:      *
 905:      * Valid parameters are listed at:
 906:      * <http://mstratman.github.io/cocoadialog/#documentation3.0/standard-dropdown_control>
 907:      *
 908:      * @param array $_passed Dialog paramenters
 909:      * @return string Output from dialog
 910:      */
 911:     public function standard_dropdown(array $_passed) {
 912:         $custom_options = [
 913:             'text' => ['string'],
 914:             'items' => ['array'],
 915:             'pulldown' => ['boolean'],
 916:             'exit_onchange' => ['boolean'],
 917:             'float' => ['boolean'],
 918:         ];
 919:         $custom_options = [
 920:             'dialog_name' => __FUNCTION__,
 921:             'required_options' => [],
 922:             'custom_options' => $custom_options
 923:         ];
 924:         $_passed = $this->_format_passed( $_passed );
 925:         $_valid = $this->_valid_options( $_passed, $custom_options );
 926:         if ( $_valid[0] ) {
 927:             return $this->_display( __FUNCTION__, $_valid[1] );
 928:         }
 929:     }
 930: }
 931: endif;
 932: 
 933: 
 934: if ( ! class_exists( 'ProgressBar' ) ):
 935: /**
 936:  * Seperate class used for interaction with CocoaDialog's progress bar.
 937:  *
 938:  * Client inintialization is built by:
 939:  *
 940:  *     $client = new ProgressBar('path to CocoaDialog.app or exec', [associative array of dialog arguements], $dialog=bool)
 941:  *
 942:  * NOTE: Currently broken due to CocoaDialog's exception thrown when opening process with stdin.
 943:  * Possibly fixable.
 944:  */
 945: class ProgressBar {
 946: 
 947:     /**
 948:      * Storage for CocoaDialog client
 949:      *
 950:      * @access private
 951:      * @var CocoaDialog
 952:      */
 953:     private $cocoa;
 954: 
 955:     /**
 956:      * Persistent storage for progress percent
 957:      *
 958:      * @access private
 959:      * @var integer
 960:      */
 961:     private $percent;
 962: 
 963:     /**
 964:      * Persistent storate for progress text
 965:      *
 966:      * @access private
 967:      * @var string
 968:      */
 969:     private $text;
 970: 
 971:     /**
 972:      * Persistent storage of read/write pipes
 973:      *
 974:      * @access private
 975:      * @var IO
 976:      */
 977:     private $pipe;
 978: 
 979:     /**
 980:      * Persistent storage of proc_open object
 981:      *
 982:      * @access private
 983:      * @var proc_open
 984:      */
 985:     private $proc;
 986: 
 987:     /**
 988:      * Progress class constructor.
 989:      *
 990:      * @param string $cocoa Path to CocoaDialog.app or exec
 991:      * @param array $_passed Progress dialog arguemnts (associative array)
 992:      * @param boolean $debug True if logging is enabled
 993:      */
 994:     public function __construct( $cocoa, array $_passed ) {
 995:         $this->cocoa = $cocoa;
 996:         if ( get_class($this->cocoa) != 'CocoaDialog' ) {
 997:             echo sprintf( "[%-8s] <%s:%d>....%s\n",
 998:                 'CRITICAL', get_class($this), __LINE__, 'invalid cocoadialog client' );
 999:             die();
1000:         }
1001:         $custom_options = [
1002:             'text' => ['string'],
1003:             'percent' => ['integer', 'double'],
1004:             'indeterminate' => ['boolean'],
1005:             'float' => ['boolean'],
1006:             'stoppable' => ['boolean'],
1007:         ];
1008:         $custom_options = [
1009:             'dialog_name' => get_class($this),
1010:             'required_options' => ['percent', 'text'],
1011:             'custom_options' => $custom_options
1012:         ];
1013:         $_passed = $this->cocoa->_format_passed( $_passed );
1014:         $_valid = $this->cocoa->_valid_options( $_passed, $custom_options );
1015:         if ( $_valid[0] ) {
1016:             $this->percent = $_valid[1]['percent'];
1017:             $this->text = $_valid[1]['text'];
1018:             $process = implode( ' ', $this->cocoa->_display( strtolower( $custom_options['dialog_name'] ), $_valid[1], $return_process=True ) );
1019:             $this->proc = proc_open( $process, [['pipe', 'r'], ['pipe', 'w']], $this->pipe );
1020:             if ( is_resource( $this->proc ) ) {
1021:                 $this->pipe[1];
1022:             }
1023:         }
1024:     }
1025: 
1026:     /**
1027:      * Update the current progress bar's state.
1028:      *
1029:      * @param integer $percent Percentage filled of progress bar dialog
1030:      * @param string $text Test of progress bar dialog
1031:      * @return integer 1 if running 0 if stopped
1032:      */
1033:     public function update( $percent=NULL, $text=NULL ) {
1034:         $this->percent = ( is_null( $percent ) ) ? $this->percent : $percent;
1035:         $this->text = ( is_null( $text ) ) ? $this->text : $text;
1036:         if ( is_resource( $this->proc ) && ( proc_get_status( $this->proc )['running'] ) ) {
1037:             fwrite( $this->pipe[0], sprintf( "%s %s\n", $this->percent, $this->text ) );
1038:             return 1;
1039:         }
1040:         else {
1041:             return $this->finish();
1042:         }
1043:     }
1044: 
1045:     /**
1046:      * Kill the progress bar dialog.
1047:      *
1048:      * @return integer 0 when killed
1049:      */
1050:     public function finish() {
1051:         proc_terminate( $this->proc );
1052:         return 0;
1053:     }
1054: 
1055: }
1056: endif;
1057: 
Alfred Bundler API documentation generated by ApiGen 2.8.0