Overview

Namespaces

  • None
  • RedBeanPHP
    • Adapter
    • BeanHelper
    • Cursor
    • Driver
    • Logger
      • RDefault
    • QueryWriter
    • RedException
    • Repository
    • Util

Classes

  • R
  • RedBean_SimpleModel
  • RedBeanPHP\Adapter\DBAdapter
  • RedBeanPHP\AssociationManager
  • RedBeanPHP\BeanCollection
  • RedBeanPHP\BeanHelper\SimpleFacadeBeanHelper
  • RedBeanPHP\Cursor\NullCursor
  • RedBeanPHP\Cursor\PDOCursor
  • RedBeanPHP\Driver\RPDO
  • RedBeanPHP\DuplicationManager
  • RedBeanPHP\Facade
  • RedBeanPHP\Finder
  • RedBeanPHP\Jsonable
  • RedBeanPHP\LabelMaker
  • RedBeanPHP\Logger\RDefault
  • RedBeanPHP\Logger\RDefault\Debug
  • RedBeanPHP\Observable
  • RedBeanPHP\OODB
  • RedBeanPHP\OODBBean
  • RedBeanPHP\QueryWriter\AQueryWriter
  • RedBeanPHP\QueryWriter\CUBRID
  • RedBeanPHP\QueryWriter\MySQL
  • RedBeanPHP\QueryWriter\PostgreSQL
  • RedBeanPHP\QueryWriter\SQLiteT
  • RedBeanPHP\R
  • RedBeanPHP\Repository
  • RedBeanPHP\Repository\Fluid
  • RedBeanPHP\Repository\Frozen
  • RedBeanPHP\SimpleModel
  • RedBeanPHP\SimpleModelHelper
  • RedBeanPHP\TagManager
  • RedBeanPHP\ToolBox
  • RedBeanPHP\Util\ArrayTool
  • RedBeanPHP\Util\DispenseHelper
  • RedBeanPHP\Util\Dump
  • RedBeanPHP\Util\MultiLoader
  • RedBeanPHP\Util\Transaction

Interfaces

  • RedBeanPHP\Adapter
  • RedBeanPHP\BeanHelper
  • RedBeanPHP\Cursor
  • RedBeanPHP\Driver
  • RedBeanPHP\Logger
  • RedBeanPHP\Observer
  • RedBeanPHP\Plugin
  • RedBeanPHP\QueryWriter

Exceptions

  • RedBeanPHP\RedException
  • RedBeanPHP\RedException\SQL

Functions

  • array_flatten
  • dmp
  • EID
  • genslots
  • Overview
  • Namespace
  • Class
   1: <?php
   2: 
   3: namespace RedBeanPHP;
   4: 
   5: use RedBeanPHP\QueryWriter as QueryWriter;
   6: use RedBeanPHP\Adapter\DBAdapter as DBAdapter;
   7: use RedBeanPHP\RedException\SQL as SQLException;
   8: use RedBeanPHP\Logger as Logger;
   9: use RedBeanPHP\Logger\RDefault as RDefault;
  10: use RedBeanPHP\Logger\RDefault\Debug as Debug;
  11: use RedBeanPHP\Adapter as Adapter;
  12: use RedBeanPHP\QueryWriter\AQueryWriter as AQueryWriter;
  13: use RedBeanPHP\RedException as RedException;
  14: use RedBeanPHP\BeanHelper\SimpleFacadeBeanHelper as SimpleFacadeBeanHelper;
  15: use RedBeanPHP\Driver\RPDO as RPDO;
  16: use RedBeanPHP\Util\MultiLoader as MultiLoader;
  17: use RedBeanPHP\Util\Transaction as Transaction;
  18: use RedBeanPHP\Util\Dump as Dump;
  19: use RedBeanPHP\Util\DispenseHelper as DispenseHelper;
  20: use RedBeanPHP\Util\ArrayTool as ArrayTool;
  21: 
  22: /**
  23:  * RedBean Facade
  24:  *
  25:  * Version Information
  26:  * RedBean Version @version 4.3
  27:  *
  28:  * This class hides the object landscape of
  29:  * RedBeanPHP behind a single letter class providing
  30:  * almost all functionality with simple static calls.
  31:  *
  32:  * @file    RedBeanPHP/Facade.php
  33:  * @author  Gabor de Mooij and the RedBeanPHP Community
  34:  * @license BSD/GPLv2
  35:  *
  36:  * @copyright
  37:  * copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
  38:  * This source file is subject to the BSD/GPLv2 License that is bundled
  39:  * with this source code in the file license.txt.
  40:  */
  41: class Facade
  42: {
  43:     /**
  44:      * RedBeanPHP version constant.
  45:      */
  46:     const C_REDBEANPHP_VERSION = '4.3';
  47: 
  48:     /**
  49:      * @var ToolBox
  50:      */
  51:     public static $toolbox;
  52: 
  53:     /**
  54:      * @var OODB
  55:      */
  56:     private static $redbean;
  57: 
  58:     /**
  59:      * @var QueryWriter
  60:      */
  61:     private static $writer;
  62: 
  63:     /**
  64:      * @var DBAdapter
  65:      */
  66:     private static $adapter;
  67: 
  68:     /**
  69:      * @var AssociationManager
  70:      */
  71:     private static $associationManager;
  72: 
  73:     /**
  74:      * @var TagManager
  75:      */
  76:     private static $tagManager;
  77: 
  78:     /**
  79:      * @var DuplicationManager
  80:      */
  81:     private static $duplicationManager;
  82: 
  83:     /**
  84:      * @var LabelMaker
  85:      */
  86:     private static $labelMaker;
  87: 
  88:     /**
  89:      * @var Finder
  90:      */
  91:     private static $finder;
  92: 
  93:     /**
  94:      * @var Logger
  95:      */
  96:     private static $logger;
  97: 
  98:     /**
  99:      * @var array
 100:      */
 101:     private static $plugins = array();
 102: 
 103:     /**
 104:      * @var string
 105:      */
 106:     private static $exportCaseStyle = 'default';
 107: 
 108:     /**
 109:      * Not in use (backward compatibility SQLHelper)
 110:      */
 111:     public static $f;
 112: 
 113:     /**
 114:      * @var string
 115:      */
 116:     public static $currentDB = '';
 117: 
 118:     /**
 119:      * @var array
 120:      */
 121:     public static $toolboxes = array();
 122: 
 123:     /**
 124:      * Internal Query function, executes the desired query. Used by
 125:      * all facade query functions. This keeps things DRY.
 126:      *
 127:      * @param string $method   desired query method (i.e. 'cell', 'col', 'exec' etc..)
 128:      * @param string $sql      the sql you want to execute
 129:      * @param array  $bindings array of values to be bound to query statement
 130:      *
 131:      * @return array
 132:      */
 133:     private static function query( $method, $sql, $bindings )
 134:     {
 135:         if ( !self::$redbean->isFrozen() ) {
 136:             try {
 137:                 $rs = Facade::$adapter->$method( $sql, $bindings );
 138:             } catch ( SQLException $exception ) {
 139:                 if ( self::$writer->sqlStateIn( $exception->getSQLState(),
 140:                     array(
 141:                         QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN,
 142:                         QueryWriter::C_SQLSTATE_NO_SUCH_TABLE )
 143:                     )
 144:                 ) {
 145:                     return ( $method === 'getCell' ) ? NULL : array();
 146:                 } else {
 147:                     throw $exception;
 148:                 }
 149:             }
 150: 
 151:             return $rs;
 152:         } else {
 153:             return Facade::$adapter->$method( $sql, $bindings );
 154:         }
 155:     }
 156: 
 157:     /**
 158:      * Returns the RedBeanPHP version string.
 159:      * The RedBeanPHP version string always has the same format "X.Y"
 160:      * where X is the major version number and Y is the minor version number.
 161:      * Point releases are not mentioned in the version string.
 162:      *
 163:      * @return string
 164:      */
 165:     public static function getVersion()
 166:     {
 167:         return self::C_REDBEANPHP_VERSION;
 168:     }
 169: 
 170:     /**
 171:      * Tests the connection.
 172:      * Returns TRUE if connection has been established and
 173:      * FALSE otherwise.
 174:      *
 175:      * @return boolean
 176:      */
 177:     public static function testConnection()
 178:     {
 179:         if ( !isset( self::$adapter ) ) return FALSE;
 180: 
 181:         $database = self::$adapter->getDatabase();
 182:         try {
 183:             @$database->connect();
 184:         } catch ( \Exception $e ) {}
 185:         return $database->isConnected();
 186:     }
 187: 
 188:     /**
 189:      * Kickstarts redbean for you. This method should be called before you start using
 190:      * RedBean. The Setup() method can be called without any arguments, in this case it will
 191:      * try to create a SQLite database in /tmp called red.db (this only works on UNIX-like systems).
 192:      *
 193:      * @param string  $dsn      Database connection string
 194:      * @param string  $username Username for database
 195:      * @param string  $password Password for database
 196:      * @param boolean $frozen   TRUE if you want to setup in frozen mode
 197:      *
 198:      * @return ToolBox
 199:      */
 200:     public static function setup( $dsn = NULL, $username = NULL, $password = NULL, $frozen = FALSE )
 201:     {
 202:         if ( is_null( $dsn ) ) {
 203:             $dsn = 'sqlite:/' . sys_get_temp_dir() . '/red.db';
 204:         }
 205: 
 206:         self::addDatabase( 'default', $dsn, $username, $password, $frozen );
 207:         self::selectDatabase( 'default' );
 208: 
 209:         return self::$toolbox;
 210:     }
 211: 
 212:     /**
 213:      * Toggles Narrow Field Mode.
 214:      * See documentation in QueryWriter.
 215:      *
 216:      * @param boolean $mode TRUE = Narrow Field Mode
 217:      *
 218:      * @return void
 219:      */
 220:     public static function setNarrowFieldMode( $mode )
 221:     {
 222:         AQueryWriter::setNarrowFieldMode( $mode );
 223:     }
 224: 
 225:     /**
 226:      * Wraps a transaction around a closure or string callback.
 227:      * If an Exception is thrown inside, the operation is automatically rolled back.
 228:      * If no Exception happens, it commits automatically.
 229:      * It also supports (simulated) nested transactions (that is useful when
 230:      * you have many methods that needs transactions but are unaware of
 231:      * each other).
 232:      *
 233:      * Example:
 234:      *
 235:      * <code>
 236:      * $from = 1;
 237:      * $to = 2;
 238:      * $amount = 300;
 239:      *
 240:      * R::transaction(function() use($from, $to, $amount)
 241:      * {
 242:      *   $accountFrom = R::load('account', $from);
 243:      *   $accountTo = R::load('account', $to);
 244:      *   $accountFrom->money -= $amount;
 245:      *   $accountTo->money += $amount;
 246:      *   R::store($accountFrom);
 247:      *   R::store($accountTo);
 248:      * });
 249:      * </code>
 250:      *
 251:      * @param callable $callback Closure (or other callable) with the transaction logic
 252:      *
 253:      * @return mixed
 254:      */
 255:     public static function transaction( $callback )
 256:     {
 257:         return Transaction::transaction( self::$adapter, $callback );
 258:     }
 259: 
 260:     /**
 261:      * Adds a database to the facade, afterwards you can select the database using
 262:      * selectDatabase($key), where $key is the name you assigned to this database.
 263:      *
 264:      * Usage:
 265:      *
 266:      * <code>
 267:      * R::addDatabase( 'database-1', 'sqlite:/tmp/db1.txt' );
 268:      * R::selectDatabase( 'database-1' ); //to select database again
 269:      * </code>
 270:      *
 271:      * This method allows you to dynamically add (and select) new databases
 272:      * to the facade. Adding a database with the same key will cause an exception.
 273:      *
 274:      * @param string      $key    ID for the database
 275:      * @param string      $dsn    DSN for the database
 276:      * @param string      $user   user for connection
 277:      * @param NULL|string $pass   password for connection
 278:      * @param bool        $frozen whether this database is frozen or not
 279:      *
 280:      * @return void
 281:      */
 282:     public static function addDatabase( $key, $dsn, $user = NULL, $pass = NULL, $frozen = FALSE )
 283:     {
 284:         if ( isset( self::$toolboxes[$key] ) ) {
 285:             throw new RedException( 'A database has already been specified for this key.' );
 286:         }
 287: 
 288:         if ( is_object($dsn) ) {
 289:             $db  = new RPDO( $dsn );
 290:             $dbType = $db->getDatabaseType();
 291:         } else {
 292:             $db = new RPDO( $dsn, $user, $pass, TRUE );
 293:             $dbType = substr( $dsn, 0, strpos( $dsn, ':' ) );
 294:         }
 295: 
 296:         $adapter = new DBAdapter( $db );
 297: 
 298:         $writers = array(
 299:             'pgsql'  => 'PostgreSQL',
 300:             'sqlite' => 'SQLiteT',
 301:             'cubrid' => 'CUBRID',
 302:             'mysql'  => 'MySQL',
 303:             'sqlsrv' => 'SQLServer',
 304:         );
 305: 
 306:         $wkey = trim( strtolower( $dbType ) );
 307:         if ( !isset( $writers[$wkey] ) ) {
 308:             $wkey = preg_replace( '/\W/', '' , $wkey );
 309:             throw new RedException( 'Unsupported database ('.$wkey.').' );
 310:         }
 311:         $writerClass = '\\RedBeanPHP\\QueryWriter\\'.$writers[$wkey];
 312:         $writer      = new $writerClass( $adapter );
 313:         $redbean     = new OODB( $writer, $frozen );
 314: 
 315:         self::$toolboxes[$key] = new ToolBox( $redbean, $adapter, $writer );
 316:     }
 317: 
 318:     /**
 319:      * Determines whether a database identified with the specified key has
 320:      * already been added to the facade. This function will return TRUE
 321:      * if the database indicated by the key is available and FALSE otherwise.
 322:      *
 323:      * @param string $key the key/name of the database to check for
 324:      *
 325:      * @return boolean
 326:      */
 327:     public static function hasDatabase( $key )
 328:     {
 329:         return ( isset( self::$toolboxes[$key] ) );
 330:     }
 331: 
 332:     /**
 333:      * Selects a different database for the Facade to work with.
 334:      * If you use the R::setup() you don't need this method. This method is meant
 335:      * for multiple database setups. This method selects the database identified by the
 336:      * database ID ($key). Use addDatabase() to add a new database, which in turn
 337:      * can be selected using selectDatabase(). If you use R::setup(), the resulting
 338:      * database will be stored under key 'default', to switch (back) to this database
 339:      * use R::selectDatabase( 'default' ). This method returns TRUE if the database has been
 340:      * switched and FALSE otherwise (for instance if you already using the specified database).
 341:      *
 342:      * @param  string $key Key of the database to select
 343:      *
 344:      * @return boolean
 345:      */
 346:     public static function selectDatabase( $key )
 347:     {
 348:         if ( self::$currentDB === $key ) {
 349:             return FALSE;
 350:         }
 351: 
 352:         if ( !isset( self::$toolboxes[$key] ) ) {
 353:             throw new RedException( 'Database not found in registry. Add database using R::addDatabase().' );
 354:         }
 355: 
 356:         self::configureFacadeWithToolbox( self::$toolboxes[$key] );
 357:         self::$currentDB = $key;
 358: 
 359:         return TRUE;
 360:     }
 361: 
 362:     /**
 363:      * Toggles DEBUG mode.
 364:      * In Debug mode all SQL that happens under the hood will
 365:      * be printed to the screen and/or logged.
 366:      * If no database connection has been configured using R::setup() or
 367:      * R::selectDatabase() this method will throw an exception.
 368:      *
 369:      * There are 2 debug styles:
 370:      *
 371:      * Classic: separate parameter bindings, explicit and complete but less readable
 372:      * Fancy:   interpersed bindings, truncates large strings, highlighted schema changes
 373:      *
 374:      * Fancy style is more readable but sometimes incomplete.
 375:      *
 376:      * The first parameter turns debugging ON or OFF.
 377:      * The second parameter indicates the mode of operation:
 378:      *
 379:      * 0 Log and write to STDOUT classic style (default)
 380:      * 1 Log only, class style
 381:      * 2 Log and write to STDOUT fancy style
 382:      * 3 Log only, fancy style
 383:      *
 384:      * This function always returns the logger instance created to generate the
 385:      * debug messages.
 386:      *
 387:      * @param boolean $tf   debug mode (TRUE or FALSE)
 388:      * @param integer $mode mode of operation
 389:      *
 390:      * @return RDefault
 391:      * @throws RedException
 392:      */
 393:     public static function debug( $tf = TRUE, $mode = 0 )
 394:     {
 395:         if ($mode > 1) {
 396:             $mode -= 2;
 397:             $logger = new Debug;
 398:         } else {
 399:             $logger = new RDefault;
 400:         }
 401: 
 402:         if ( !isset( self::$adapter ) ) {
 403:             throw new RedException( 'Use R::setup() first.' );
 404:         }
 405:         $logger->setMode($mode);
 406:         self::$adapter->getDatabase()->setDebugMode( $tf, $logger );
 407: 
 408:         return $logger;
 409:     }
 410: 
 411:     /**
 412:      * Turns on the fancy debugger.
 413:      * In 'fancy' mode the debugger will output queries with bound
 414:      * parameters inside the SQL itself. This method has been added to
 415:      * offer a convenient way to activate the fancy debugger system
 416:      * in one call.
 417:      *
 418:      * @param boolean $toggle TRUE to activate debugger and select 'fancy' mode
 419:      *
 420:      * @return void
 421:      */
 422:     public static function fancyDebug( $toggle = TRUE )
 423:     {
 424:         self::debug( $toggle, 2 );
 425:     }
 426: 
 427:     /**
 428:     * Inspects the database schema. If you pass the type of a bean this
 429:     * method will return the fields of its table in the database.
 430:     * The keys of this array will be the field names and the values will be
 431:     * the column types used to store their values.
 432:     * If no type is passed, this method returns a list of all tables in the database.
 433:     *
 434:     * @param string $type Type of bean (i.e. table) you want to inspect
 435:     *
 436:     * @return array
 437:     */
 438:     public static function inspect( $type = NULL )
 439:     {
 440:         return ($type === NULL) ? self::$writer->getTables() : self::$writer->getColumns( $type );
 441:     }
 442: 
 443:     /**
 444:      * Stores a bean in the database. This method takes a
 445:      * OODBBean Bean Object $bean and stores it
 446:      * in the database. If the database schema is not compatible
 447:      * with this bean and RedBean runs in fluid mode the schema
 448:      * will be altered to store the bean correctly.
 449:      * If the database schema is not compatible with this bean and
 450:      * RedBean runs in frozen mode it will throw an exception.
 451:      * This function returns the primary key ID of the inserted
 452:      * bean.
 453:      *
 454:      * The return value is an integer if possible. If it is not possible to
 455:      * represent the value as an integer a string will be returned.
 456:      *
 457:      * @param OODBBean|SimpleModel $bean bean to store
 458:      *
 459:      * @return integer|string
 460:      */
 461:     public static function store( $bean )
 462:     {
 463:         return self::$redbean->store( $bean );
 464:     }
 465: 
 466:     /**
 467:      * Toggles fluid or frozen mode. In fluid mode the database
 468:      * structure is adjusted to accomodate your objects. In frozen mode
 469:      * this is not the case.
 470:      *
 471:      * You can also pass an array containing a selection of frozen types.
 472:      * Let's call this chilly mode, it's just like fluid mode except that
 473:      * certain types (i.e. tables) aren't touched.
 474:      *
 475:      * @param boolean|array $trueFalse
 476:      */
 477:     public static function freeze( $tf = TRUE )
 478:     {
 479:         self::$redbean->freeze( $tf );
 480:     }
 481: 
 482:     /**
 483:      * Loads multiple types of beans with the same ID.
 484:      * This might look like a strange method, however it can be useful
 485:      * for loading a one-to-one relation.
 486:      *
 487:      * Usage:
 488:      * list( $author, $bio ) = R::loadMulti( 'author, bio', $id );
 489:      *
 490:      * @param string|array $types the set of types to load at once
 491:      * @param mixed        $id    the common ID
 492:      *
 493:      * @return OODBBean
 494:      */
 495:     public static function loadMulti( $types, $id )
 496:     {
 497:         return MultiLoader::load( self::$redbean, $types, $id );
 498:     }
 499: 
 500:     /**
 501:      * Loads a bean from the object database.
 502:      * It searches for a OODBBean Bean Object in the
 503:      * database. It does not matter how this bean has been stored.
 504:      * RedBean uses the primary key ID $id and the string $type
 505:      * to find the bean. The $type specifies what kind of bean you
 506:      * are looking for; this is the same type as used with the
 507:      * dispense() function. If RedBean finds the bean it will return
 508:      * the OODB Bean object; if it cannot find the bean
 509:      * RedBean will return a new bean of type $type and with
 510:      * primary key ID 0. In the latter case it acts basically the
 511:      * same as dispense().
 512:      *
 513:      * Important note:
 514:      * If the bean cannot be found in the database a new bean of
 515:      * the specified type will be generated and returned.
 516:      *
 517:      * @param string  $type type of bean you want to load
 518:      * @param integer $id   ID of the bean you want to load
 519:      *
 520:      * @return OODBBean
 521:      */
 522:     public static function load( $type, $id )
 523:     {
 524:         return self::$redbean->load( $type, $id );
 525:     }
 526: 
 527:     /**
 528:      * Removes a bean from the database.
 529:      * This function will remove the specified OODBBean
 530:      * Bean Object from the database.
 531:      *
 532:      * This facade method also accepts a type-id combination,
 533:      * in the latter case this method will attempt to load the specified bean
 534:      * and THEN trash it.
 535:      *
 536:      * @param string|OODBBean|SimpleModel $bean bean you want to remove from database
 537:      * @param integer                     $id   ID if the bean to trash (optional, type-id variant only)
 538:      *
 539:      * @return void
 540:      */
 541:     public static function trash( $beanOrType, $id = NULL )
 542:     {
 543:         if ( is_string( $beanOrType ) ) return self::trash( self::load( $beanOrType, $id ) );
 544:         return self::$redbean->trash( $beanOrType );
 545:     }
 546: 
 547:     /**
 548:      * Dispenses a new RedBean OODB Bean for use with
 549:      * the rest of the methods.
 550:      *
 551:      * @param string|array $typeOrBeanArray   type or bean array to import
 552:      * @param integer      $number            number of beans to dispense
 553:      * @param boolean      $alwaysReturnArray if TRUE always returns the result as an array
 554:      *
 555:      * @return array|OODBBean
 556:      */
 557:     public static function dispense( $typeOrBeanArray, $num = 1, $alwaysReturnArray = FALSE )
 558:     {
 559:         return DispenseHelper::dispense( self::$redbean, $typeOrBeanArray, $num, $alwaysReturnArray );
 560:     }
 561: 
 562:     /**
 563:      * Takes a comma separated list of bean types
 564:      * and dispenses these beans. For each type in the list
 565:      * you can specify the number of beans to be dispensed.
 566:      *
 567:      * Usage:
 568:      *
 569:      * <code>
 570:      * list( $book, $page, $text ) = R::dispenseAll( 'book,page,text' );
 571:      * </code>
 572:      *
 573:      * This will dispense a book, a page and a text. This way you can
 574:      * quickly dispense beans of various types in just one line of code.
 575:      *
 576:      * Usage:
 577:      *
 578:      * <code>
 579:      * list($book, $pages) = R::dispenseAll('book,page*100');
 580:      * </code>
 581:      *
 582:      * This returns an array with a book bean and then another array
 583:      * containing 100 page beans.
 584:      *
 585:      * @param string  $order      a description of the desired dispense order using the syntax above
 586:      * @param boolean $onlyArrays return only arrays even if amount < 2
 587:      *
 588:      * @return array
 589:      */
 590:     public static function dispenseAll( $order, $onlyArrays = FALSE )
 591:     {
 592:         return DispenseHelper::dispenseAll( self::$redbean, $order, $onlyArrays );
 593:     }
 594: 
 595:     /**
 596:      * Convience method. Tries to find beans of a certain type,
 597:      * if no beans are found, it dispenses a bean of that type.
 598:      *
 599:      * @param  string $type     type of bean you are looking for
 600:      * @param  string $sql      SQL code for finding the bean
 601:      * @param  array  $bindings parameters to bind to SQL
 602:      *
 603:      * @return array
 604:      */
 605:     public static function findOrDispense( $type, $sql = NULL, $bindings = array() )
 606:     {
 607:         return self::$finder->findOrDispense( $type, $sql, $bindings );
 608:     }
 609: 
 610:     /**
 611:      * Finds a bean using a type and a where clause (SQL).
 612:      * As with most Query tools in RedBean you can provide values to
 613:      * be inserted in the SQL statement by populating the value
 614:      * array parameter; you can either use the question mark notation
 615:      * or the slot-notation (:keyname).
 616:      *
 617:      * @param string $type     the type of bean you are looking for
 618:      * @param string $sql      SQL query to find the desired bean, starting right after WHERE clause
 619:      * @param array  $bindings array of values to be bound to parameters in query
 620:      *
 621:      * @return array
 622:      */
 623:     public static function find( $type, $sql = NULL, $bindings = array() )
 624:     {
 625:         return self::$finder->find( $type, $sql, $bindings );
 626:     }
 627: 
 628:     /**
 629:      * @see Facade::find
 630:      *      The findAll() method differs from the find() method in that it does
 631:      *      not assume a WHERE-clause, so this is valid:
 632:      *
 633:      * R::findAll('person',' ORDER BY name DESC ');
 634:      *
 635:      * Your SQL does not have to start with a valid WHERE-clause condition.
 636:      *
 637:      * @param string $type     the type of bean you are looking for
 638:      * @param string $sql      SQL query to find the desired bean, starting right after WHERE clause
 639:      * @param array  $bindings array of values to be bound to parameters in query
 640:      *
 641:      * @return array
 642:      */
 643:     public static function findAll( $type, $sql = NULL, $bindings = array() )
 644:     {
 645:         return self::$finder->find( $type, $sql, $bindings );
 646:     }
 647: 
 648:     /**
 649:      * @see Facade::find
 650:      * The variation also exports the beans (i.e. it returns arrays).
 651:      *
 652:      * @param string $type     the type of bean you are looking for
 653:      * @param string $sql      SQL query to find the desired bean, starting right after WHERE clause
 654:      * @param array  $bindings array of values to be bound to parameters in query
 655:      *
 656:      * @return array
 657:      */
 658:     public static function findAndExport( $type, $sql = NULL, $bindings = array() )
 659:     {
 660:         return self::$finder->findAndExport( $type, $sql, $bindings );
 661:     }
 662: 
 663:     /**
 664:      * @see Facade::find
 665:      * This variation returns the first bean only.
 666:      *
 667:      * @param string $type     the type of bean you are looking for
 668:      * @param string $sql      SQL query to find the desired bean, starting right after WHERE clause
 669:      * @param array  $bindings array of values to be bound to parameters in query
 670:      *
 671:      * @return OODBBean
 672:      */
 673:     public static function findOne( $type, $sql = NULL, $bindings = array() )
 674:     {
 675:         return self::$finder->findOne( $type, $sql, $bindings );
 676:     }
 677: 
 678:     /**
 679:      * @see Facade::find
 680:      * This variation returns the last bean only.
 681:      *
 682:      * @param string $type     the type of bean you are looking for
 683:      * @param string $sql      SQL query to find the desired bean, starting right after WHERE clause
 684:      * @param array  $bindings array of values to be bound to parameters in query
 685:      *
 686:      * @return OODBBean
 687:      */
 688:     public static function findLast( $type, $sql = NULL, $bindings = array() )
 689:     {
 690:         return self::$finder->findLast( $type, $sql, $bindings );
 691:     }
 692: 
 693:     /**
 694:      * Finds a bean collection.
 695:      * Use this for large datasets.
 696:      *
 697:      * @param string $type     the type of bean you are looking for
 698:      * @param string $sql      SQL query to find the desired bean, starting right after WHERE clause
 699:      * @param array  $bindings array of values to be bound to parameters in query
 700:      *
 701:      * @return BeanCollection
 702:      */
 703:     public static function findCollection( $type, $sql = NULL, $bindings = array() )
 704:     {
 705:         return self::$finder->findCollection( $type, $sql, $bindings );
 706:     }
 707: 
 708:     /**
 709:      * Finds multiple types of beans at once and offers additional
 710:      * remapping functionality. This is a very powerful yet complex function.
 711:      * For details see Finder::findMulti().
 712:      *
 713:      * @see Finder::findMulti()
 714:      *
 715:      * @param array|string $types      a list of bean types to find
 716:      * @param string|array $sqlOrArr   SQL query string or result set array
 717:      * @param array        $bindings   SQL bindings
 718:      * @param array        $remappings an array of remapping arrays containing closures
 719:      *
 720:      * @return array
 721:      */
 722:     public static function findMulti( $types, $sql, $bindings = array(), $remappings = array() )
 723:     {
 724:         return self::$finder->findMulti( $types, $sql, $bindings, $remappings );
 725:     }
 726: 
 727:     /**
 728:      * Returns an array of beans. Pass a type and a series of ids and
 729:      * this method will bring you the corresponding beans.
 730:      *
 731:      * important note: Because this method loads beans using the load()
 732:      * function (but faster) it will return empty beans with ID 0 for
 733:      * every bean that could not be located. The resulting beans will have the
 734:      * passed IDs as their keys.
 735:      *
 736:      * @param string $type type of beans
 737:      * @param array  $ids  ids to load
 738:      *
 739:      * @return array
 740:      */
 741:     public static function batch( $type, $ids )
 742:     {
 743:         return self::$redbean->batch( $type, $ids );
 744:     }
 745: 
 746:     /**
 747:      * @see Facade::batch
 748:      *
 749:      * Alias for batch(). Batch method is older but since we added so-called *All
 750:      * methods like storeAll, trashAll, dispenseAll and findAll it seemed logical to
 751:      * improve the consistency of the Facade API and also add an alias for batch() called
 752:      * loadAll.
 753:      *
 754:      * @param string $type type of beans
 755:      * @param array  $ids  ids to load
 756:      *
 757:      * @return array
 758:      */
 759:     public static function loadAll( $type, $ids )
 760:     {
 761:         return self::$redbean->batch( $type, $ids );
 762:     }
 763: 
 764:     /**
 765:      * Convenience function to execute Queries directly.
 766:      * Executes SQL.
 767:      *
 768:      * @param string $sql       SQL query to execute
 769:      * @param array  $bindings  a list of values to be bound to query parameters
 770:      *
 771:      * @return integer
 772:      */
 773:     public static function exec( $sql, $bindings = array() )
 774:     {
 775:         return self::query( 'exec', $sql, $bindings );
 776:     }
 777: 
 778:     /**
 779:      * Convenience function to execute Queries directly.
 780:      * Executes SQL.
 781:      *
 782:      * @param string $sql      SQL query to execute
 783:      * @param array  $bindings a list of values to be bound to query parameters
 784:      *
 785:      * @return array
 786:      */
 787:     public static function getAll( $sql, $bindings = array() )
 788:     {
 789:         return self::query( 'get', $sql, $bindings );
 790:     }
 791: 
 792:     /**
 793:      * Convenience function to execute Queries directly.
 794:      * Executes SQL.
 795:      *
 796:      * @param string $sql      SQL query to execute
 797:      * @param array  $bindings a list of values to be bound to query parameters
 798:      *
 799:      * @return string
 800:      */
 801:     public static function getCell( $sql, $bindings = array() )
 802:     {
 803:         return self::query( 'getCell', $sql, $bindings );
 804:     }
 805: 
 806:     /**
 807:      * Convenience function to execute Queries directly.
 808:      * Executes SQL.
 809:      *
 810:      * @param string $sql      SQL query to execute
 811:      * @param array  $bindings a list of values to be bound to query parameters
 812:      *
 813:      * @return array
 814:      */
 815:     public static function getRow( $sql, $bindings = array() )
 816:     {
 817:         return self::query( 'getRow', $sql, $bindings );
 818:     }
 819: 
 820:     /**
 821:      * Convenience function to execute Queries directly.
 822:      * Executes SQL.
 823:      *
 824:      * @param string $sql      SQL query to execute
 825:      * @param array  $bindings a list of values to be bound to query parameters
 826:      *
 827:      * @return array
 828:      */
 829:     public static function getCol( $sql, $bindings = array() )
 830:     {
 831:         return self::query( 'getCol', $sql, $bindings );
 832:     }
 833: 
 834:     /**
 835:      * Convenience function to execute Queries directly.
 836:      * Executes SQL.
 837:      * Results will be returned as an associative array. The first
 838:      * column in the select clause will be used for the keys in this array and
 839:      * the second column will be used for the values. If only one column is
 840:      * selected in the query, both key and value of the array will have the
 841:      * value of this field for each row.
 842:      *
 843:      * @param string $sql      SQL query to execute
 844:      * @param array  $bindings a list of values to be bound to query parameters
 845:      *
 846:      * @return array
 847:      */
 848:     public static function getAssoc( $sql, $bindings = array() )
 849:     {
 850:         return self::query( 'getAssoc', $sql, $bindings );
 851:     }
 852: 
 853:     /**
 854:      * Convenience function to execute Queries directly.
 855:      * Executes SQL.
 856:      * Results will be returned as an associative array indexed by the first
 857:      * column in the select.
 858:      *
 859:      * @param string $sql      SQL query to execute
 860:      * @param array  $bindings a list of values to be bound to query parameters
 861:      *
 862:      * @return array
 863:      */
 864:     public static function getAssocRow( $sql, $bindings = array() )
 865:     {
 866:         return self::query( 'getAssocRow', $sql, $bindings );
 867:     }
 868: 
 869:     /**
 870:      * Returns the insert ID for databases that support/require this
 871:      * functionality. Alias for R::getAdapter()->getInsertID().
 872:      *
 873:      * @return mixed
 874:      */
 875:     public static function getInsertID()
 876:     {
 877:         return self::$adapter->getInsertID();
 878:     }
 879: 
 880:     /**
 881:      * Makes a copy of a bean. This method makes a deep copy
 882:      * of the bean.The copy will have the following features.
 883:      * - All beans in own-lists will be duplicated as well
 884:      * - All references to shared beans will be copied but not the shared beans themselves
 885:      * - All references to parent objects (_id fields) will be copied but not the parents themselves
 886:      * In most cases this is the desired scenario for copying beans.
 887:      * This function uses a trail-array to prevent infinite recursion, if a recursive bean is found
 888:      * (i.e. one that already has been processed) the ID of the bean will be returned.
 889:      * This should not happen though.
 890:      *
 891:      * Note:
 892:      * This function does a reflectional database query so it may be slow.
 893:      *
 894:      * @deprecated
 895:      * This function is deprecated in favour of R::duplicate().
 896:      * This function has a confusing method signature, the R::duplicate() function
 897:      * only accepts two arguments: bean and filters.
 898:      *
 899:      * @param OODBBean $bean  bean to be copied
 900:      * @param array    $trail for internal usage, pass array()
 901:      * @param boolean  $pid   for internal usage
 902:      * @param array    $white white list filter with bean types to duplicate
 903:      *
 904:      * @return array
 905:      */
 906:     public static function dup( $bean, $trail = array(), $pid = FALSE, $filters = array() )
 907:     {
 908:         self::$duplicationManager->setFilters( $filters );
 909:         return self::$duplicationManager->dup( $bean, $trail, $pid );
 910:     }
 911: 
 912:     /**
 913:      * Makes a deep copy of a bean. This method makes a deep copy
 914:      * of the bean.The copy will have the following:
 915:      *
 916:      * * All beans in own-lists will be duplicated as well
 917:      * * All references to shared beans will be copied but not the shared beans themselves
 918:      * * All references to parent objects (_id fields) will be copied but not the parents themselves
 919:      *
 920:      * In most cases this is the desired scenario for copying beans.
 921:      * This function uses a trail-array to prevent infinite recursion, if a recursive bean is found
 922:      * (i.e. one that already has been processed) the ID of the bean will be returned.
 923:      * This should not happen though.
 924:      *
 925:      * Note:
 926:      * This function does a reflectional database query so it may be slow.
 927:      *
 928:      * Note:
 929:      * This is a simplified version of the deprecated R::dup() function.
 930:      *
 931:      * @param OODBBean $bean  bean to be copied
 932:      * @param array    $white white list filter with bean types to duplicate
 933:      *
 934:      * @return array
 935:      */
 936:     public static function duplicate( $bean, $filters = array() )
 937:     {
 938:         return self::dup( $bean, array(), FALSE, $filters );
 939:     }
 940: 
 941:     /**
 942:      * Exports a collection of beans. Handy for XML/JSON exports with a
 943:      * Javascript framework like Dojo or ExtJS.
 944:      * What will be exported:
 945:      *
 946:      * * contents of the bean
 947:      * * all own bean lists (recursively)
 948:      * * all shared beans (not THEIR own lists)
 949:      *
 950:      * @param    array|OODBBean $beans   beans to be exported
 951:      * @param    boolean        $parents whether you want parent beans to be exported
 952:      * @param    array          $filters whitelist of types
 953:      *
 954:      * @return array
 955:      */
 956:     public static function exportAll( $beans, $parents = FALSE, $filters = array())
 957:     {
 958:         return self::$duplicationManager->exportAll( $beans, $parents, $filters, self::$exportCaseStyle );
 959:     }
 960: 
 961:     /**
 962:      * Selects case style for export.
 963:      * This will determine the case style for the keys of exported beans (see exportAll).
 964:      * The following options are accepted:
 965:      *
 966:      * * 'default' RedBeanPHP by default enforces Snake Case (i.e. book_id is_valid )
 967:      * * 'camel'   Camel Case   (i.e. bookId isValid   )
 968:      * * 'dolphin' Dolphin Case (i.e. bookID isValid   ) Like CamelCase but ID is written all uppercase
 969:      *
 970:      * @warning RedBeanPHP transforms camelCase to snake_case using a slightly different
 971:      * algorithm, it also converts isACL to is_acl (not is_a_c_l) and bookID to book_id.
 972:      * Due to information loss this cannot be corrected. However if you might try
 973:      * DolphinCase for IDs it takes into account the exception concerning IDs.
 974:      *
 975:      * @param string $caseStyle case style identifier
 976:      *
 977:      * @return void
 978:      */
 979:     public static function useExportCase( $caseStyle = 'default' )
 980:     {
 981:         if ( !in_array( $caseStyle, array( 'default', 'camel', 'dolphin' ) ) ) throw new RedException( 'Invalid case selected.' );
 982:         self::$exportCaseStyle = $caseStyle;
 983:     }
 984: 
 985:     /**
 986:      * Converts a series of rows to beans.
 987:      * This method converts a series of rows to beans.
 988:      * The type of the desired output beans can be specified in the
 989:      * first parameter. The second parameter is meant for the database
 990:      * result rows.
 991:      *
 992:      * Usage:
 993:      *
 994:      * <code>
 995:      * $rows = R::getAll( 'SELECT * FROM ...' )
 996:      * $beans = R::convertToBeans( $rows );
 997:      * </code>
 998:      *
 999:      * As of version 4.3.2 you can specify a meta-mask.
1000:      * Data from columns with names starting with the value specified in the mask
1001:      * will be transferred to the meta section of a bean (under data.bundle).
1002:      *
1003:      * <code>
1004:      * $rows = R::getAll( 'SELECT FROM... COUNT(*) AS extra_count ...' );
1005:      * $beans = R::convertToBeans( $rows );
1006:      * $bean = reset( $beans );
1007:      * $data = $bean->getMeta( 'data.bundle' );
1008:      * $extra_count = $data['extra_count'];
1009:      * </code>
1010:      *
1011:      * @param string $type type of beans to produce
1012:      * @param array  $rows must contain an array of array
1013:      *
1014:      * @return array
1015:      */
1016:     public static function convertToBeans( $type, $rows, $metamask = NULL )
1017:     {
1018:         return self::$redbean->convertToBeans( $type, $rows, $metamask );
1019:     }
1020: 
1021:     /**
1022:      * Just like converToBeans, but for one bean.
1023:      * @see convertToBeans for more details.
1024:      *
1025:      * @param string $type type of beans to produce
1026:      * @param array  $row  one row from the database
1027:      *
1028:      * @return array
1029:      */
1030:     public static function convertToBean( $type, $row, $metamask = NULL )
1031:     {
1032:         $beans = self::$redbean->convertToBeans( $type, array( $row ), $metamask );
1033:         $bean  = reset( $beans );
1034:         return $bean;
1035:     }
1036: 
1037:     /**
1038:      * Part of RedBeanPHP Tagging API.
1039:      * Tests whether a bean has been associated with one ore more
1040:      * of the listed tags. If the third parameter is TRUE this method
1041:      * will return TRUE only if all tags that have been specified are indeed
1042:      * associated with the given bean, otherwise FALSE.
1043:      * If the third parameter is FALSE this
1044:      * method will return TRUE if one of the tags matches, FALSE if none
1045:      * match.
1046:      *
1047:      * @param  OODBBean $bean bean to check for tags
1048:      * @param  array    $tags list of tags
1049:      * @param  boolean  $all  whether they must all match or just some
1050:      *
1051:      * @return boolean
1052:      */
1053:     public static function hasTag( $bean, $tags, $all = FALSE )
1054:     {
1055:         return self::$tagManager->hasTag( $bean, $tags, $all );
1056:     }
1057: 
1058:     /**
1059:      * Part of RedBeanPHP Tagging API.
1060:      * Removes all specified tags from the bean. The tags specified in
1061:      * the second parameter will no longer be associated with the bean.
1062:      *
1063:      * @param  OODBBean $bean    tagged bean
1064:      * @param  array    $tagList list of tags (names)
1065:      *
1066:      * @return void
1067:      */
1068:     public static function untag( $bean, $tagList )
1069:     {
1070:         self::$tagManager->untag( $bean, $tagList );
1071:     }
1072: 
1073:     /**
1074:      * Part of RedBeanPHP Tagging API.
1075:      * Tags a bean or returns tags associated with a bean.
1076:      * If $tagList is NULL or omitted this method will return a
1077:      * comma separated list of tags associated with the bean provided.
1078:      * If $tagList is a comma separated list (string) of tags all tags will
1079:      * be associated with the bean.
1080:      * You may also pass an array instead of a string.
1081:      *
1082:      * @param OODBBean $bean    bean to tag
1083:      * @param mixed    $tagList tags to attach to the specified bean
1084:      *
1085:      * @return string
1086:      */
1087:     public static function tag( OODBBean $bean, $tagList = NULL )
1088:     {
1089:         return self::$tagManager->tag( $bean, $tagList );
1090:     }
1091: 
1092:     /**
1093:      * Part of RedBeanPHP Tagging API.
1094:      * Adds tags to a bean.
1095:      * If $tagList is a comma separated list of tags all tags will
1096:      * be associated with the bean.
1097:      * You may also pass an array instead of a string.
1098:      *
1099:      * @param OODBBean $bean    bean to tag
1100:      * @param array    $tagList list of tags to add to bean
1101:      *
1102:      * @return void
1103:      */
1104:     public static function addTags( OODBBean $bean, $tagList )
1105:     {
1106:         self::$tagManager->addTags( $bean, $tagList );
1107:     }
1108: 
1109:     /**
1110:      * Part of RedBeanPHP Tagging API.
1111:      * Returns all beans that have been tagged with one of the tags given.
1112:      *
1113:      * @param string $beanType type of bean you are looking for
1114:      * @param array  $tagList  list of tags to match
1115:      * @param string $sql      additional SQL query snippet
1116:      * @param array  $bindings a list of values to bind to the query parameters
1117:      *
1118:      * @return array
1119:      */
1120:     public static function tagged( $beanType, $tagList, $sql = '', $bindings = array() )
1121:     {
1122:         return self::$tagManager->tagged( $beanType, $tagList, $sql, $bindings );
1123:     }
1124: 
1125:     /**
1126:      * Part of RedBeanPHP Tagging API.
1127:      * Returns all beans that have been tagged with ALL of the tags given.
1128:      *
1129:      * @param string $beanType type of bean you are looking for
1130:      * @param array  $tagList  list of tags to match
1131:      * @param string $sql      additional SQL query snippet
1132:      * @param array  $bindings a list of values to bind to the query parameters
1133:      *
1134:      * @return array
1135:      */
1136:     public static function taggedAll( $beanType, $tagList, $sql = '', $bindings = array() )
1137:     {
1138:         return self::$tagManager->taggedAll( $beanType, $tagList, $sql, $bindings );
1139:     }
1140: 
1141:     /**
1142:      * Wipes all beans of type $beanType.
1143:      *
1144:      * @param string $beanType type of bean you want to destroy entirely
1145:      *
1146:      * @return boolean
1147:      */
1148:     public static function wipe( $beanType )
1149:     {
1150:         return Facade::$redbean->wipe( $beanType );
1151:     }
1152: 
1153:     /**
1154:      * Counts the number of beans of type $type.
1155:      * This method accepts a second argument to modify the count-query.
1156:      * A third argument can be used to provide bindings for the SQL snippet.
1157:      *
1158:      * @param string $type     type of bean we are looking for
1159:      * @param string $addSQL   additional SQL snippet
1160:      * @param array  $bindings parameters to bind to SQL
1161:      *
1162:      * @return integer
1163:      */
1164:     public static function count( $type, $addSQL = '', $bindings = array() )
1165:     {
1166:         return Facade::$redbean->count( $type, $addSQL, $bindings );
1167:     }
1168: 
1169:     /**
1170:      * Configures the facade, want to have a new Writer? A new Object Database or a new
1171:      * Adapter and you want it on-the-fly? Use this method to hot-swap your facade with a new
1172:      * toolbox.
1173:      *
1174:      * @param ToolBox $tb toolbox to configure facade with
1175:      *
1176:      * @return ToolBox
1177:      */
1178:     public static function configureFacadeWithToolbox( ToolBox $tb )
1179:     {
1180:         $oldTools                 = self::$toolbox;
1181:         self::$toolbox            = $tb;
1182:         self::$writer             = self::$toolbox->getWriter();
1183:         self::$adapter            = self::$toolbox->getDatabaseAdapter();
1184:         self::$redbean            = self::$toolbox->getRedBean();
1185:         self::$finder             = new Finder( self::$toolbox );
1186:         self::$associationManager = new AssociationManager( self::$toolbox );
1187:         self::$redbean->setAssociationManager( self::$associationManager );
1188:         self::$labelMaker         = new LabelMaker( self::$toolbox );
1189:         $helper                   = new SimpleModelHelper();
1190:         $helper->attachEventListeners( self::$redbean );
1191:         self::$redbean->setBeanHelper( new SimpleFacadeBeanHelper );
1192:         self::$duplicationManager = new DuplicationManager( self::$toolbox );
1193:         self::$tagManager         = new TagManager( self::$toolbox );
1194:         return $oldTools;
1195:     }
1196: 
1197:     /**
1198:      * Facade Convience method for adapter transaction system.
1199:      * Begins a transaction.
1200:      *
1201:      * @return bool
1202:      */
1203:     public static function begin()
1204:     {
1205:         if ( !self::$redbean->isFrozen() ) return FALSE;
1206:         self::$adapter->startTransaction();
1207:         return TRUE;
1208:     }
1209: 
1210:     /**
1211:      * Facade Convience method for adapter transaction system.
1212:      * Commits a transaction.
1213:      *
1214:      * @return bool
1215:      */
1216:     public static function commit()
1217:     {
1218:         if ( !self::$redbean->isFrozen() ) return FALSE;
1219:         self::$adapter->commit();
1220:         return TRUE;
1221:     }
1222: 
1223:     /**
1224:      * Facade Convience method for adapter transaction system.
1225:      * Rolls back a transaction.
1226:      *
1227:      * @return bool
1228:      */
1229:     public static function rollback()
1230:     {
1231:         if ( !self::$redbean->isFrozen() ) return FALSE;
1232:         self::$adapter->rollback();
1233:         return TRUE;
1234:     }
1235: 
1236:     /**
1237:      * Returns a list of columns. Format of this array:
1238:      * array( fieldname => type )
1239:      * Note that this method only works in fluid mode because it might be
1240:      * quite heavy on production servers!
1241:      *
1242:      * @param  string $table name of the table (not type) you want to get columns of
1243:      *
1244:      * @return array
1245:      */
1246:     public static function getColumns( $table )
1247:     {
1248:         return self::$writer->getColumns( $table );
1249:     }
1250: 
1251:     /**
1252:      * Generates question mark slots for an array of values.
1253:      *
1254:      * @param array  $array array to generate question mark slots for
1255:      *
1256:      * @return string
1257:      */
1258:     public static function genSlots( $array, $template = NULL )
1259:     {
1260:         return ArrayTool::genSlots( $array, $template );
1261:     }
1262: 
1263:     /**
1264:      * Flattens a multi dimensional bindings array for use with genSlots().
1265:      *
1266:      * @param array $array array to flatten
1267:      *
1268:      * @return array
1269:      */
1270:     public static function flat( $array, $result = array() )
1271:     {
1272:         return ArrayTool::flat( $array, $result );
1273:     }
1274: 
1275:     /**
1276:      * Nukes the entire database.
1277:      * This will remove all schema structures from the database.
1278:      * Only works in fluid mode. Be careful with this method.
1279:      *
1280:      * @warning dangerous method, will remove all tables, columns etc.
1281:      *
1282:      * @return void
1283:      */
1284:     public static function nuke()
1285:     {
1286:         if ( !self::$redbean->isFrozen() ) {
1287:             self::$writer->wipeAll();
1288:         }
1289:     }
1290: 
1291:     /**
1292:      * Short hand function to store a set of beans at once, IDs will be
1293:      * returned as an array. For information please consult the R::store()
1294:      * function.
1295:      * A loop saver.
1296:      *
1297:      * @param array $beans list of beans to be stored
1298:      *
1299:      * @return array
1300:      */
1301:     public static function storeAll( $beans )
1302:     {
1303:         $ids = array();
1304:         foreach ( $beans as $bean ) {
1305:             $ids[] = self::store( $bean );
1306:         }
1307:         return $ids;
1308:     }
1309: 
1310:     /**
1311:      * Short hand function to trash a set of beans at once.
1312:      * For information please consult the R::trash() function.
1313:      * A loop saver.
1314:      *
1315:      * @param array $beans list of beans to be trashed
1316:      *
1317:      * @return void
1318:      */
1319:     public static function trashAll( $beans )
1320:     {
1321:         foreach ( $beans as $bean ) {
1322:             self::trash( $bean );
1323:         }
1324:     }
1325: 
1326:     /**
1327:      * Toggles Writer Cache.
1328:      * Turns the Writer Cache on or off. The Writer Cache is a simple
1329:      * query based caching system that may improve performance without the need
1330:      * for cache management. This caching system will cache non-modifying queries
1331:      * that are marked with special SQL comments. As soon as a non-marked query
1332:      * gets executed the cache will be flushed. Only non-modifying select queries
1333:      * have been marked therefore this mechanism is a rather safe way of caching, requiring
1334:      * no explicit flushes or reloads. Of course this does not apply if you intend to test
1335:      * or simulate concurrent querying.
1336:      *
1337:      * @param boolean $yesNo TRUE to enable cache, FALSE to disable cache
1338:      *
1339:      * @return void
1340:      */
1341:     public static function useWriterCache( $yesNo )
1342:     {
1343:         self::getWriter()->setUseCache( $yesNo );
1344:     }
1345: 
1346:     /**
1347:      * A label is a bean with only an id, type and name property.
1348:      * This function will dispense beans for all entries in the array. The
1349:      * values of the array will be assigned to the name property of each
1350:      * individual bean.
1351:      *
1352:      * @param string $type   type of beans you would like to have
1353:      * @param array  $labels list of labels, names for each bean
1354:      *
1355:      * @return array
1356:      */
1357:     public static function dispenseLabels( $type, $labels )
1358:     {
1359:         return self::$labelMaker->dispenseLabels( $type, $labels );
1360:     }
1361: 
1362:     /**
1363:      * Generates and returns an ENUM value. This is how RedBeanPHP handles ENUMs.
1364:      * Either returns a (newly created) bean respresenting the desired ENUM
1365:      * value or returns a list of all enums for the type.
1366:      *
1367:      * To obtain (and add if necessary) an ENUM value:
1368:      *
1369:      * <code>
1370:      * $tea->flavour = R::enum( 'flavour:apple' );
1371:      * </code>
1372:      *
1373:      * Returns a bean of type 'flavour' with  name = apple.
1374:      * This will add a bean with property name (set to APPLE) to the database
1375:      * if it does not exist yet.
1376:      *
1377:      * To obtain all flavours:
1378:      *
1379:      * <code>
1380:      * R::enum('flavour');
1381:      * </code>
1382:      *
1383:      * To get a list of all flavour names:
1384:      *
1385:      * <code>
1386:      * R::gatherLabels( R::enum( 'flavour' ) );
1387:      * </code>
1388:      *
1389:      * @param string $enum either type or type-value
1390:      *
1391:      * @return array|OODBBean
1392:      */
1393:     public static function enum( $enum )
1394:     {
1395:         return self::$labelMaker->enum( $enum );
1396:     }
1397: 
1398:     /**
1399:      * Gathers labels from beans. This function loops through the beans,
1400:      * collects the values of the name properties of each individual bean
1401:      * and stores the names in a new array. The array then gets sorted using the
1402:      * default sort function of PHP (sort).
1403:      *
1404:      * @param array $beans list of beans to loop
1405:      *
1406:      * @return array
1407:      */
1408:     public static function gatherLabels( $beans )
1409:     {
1410:         return self::$labelMaker->gatherLabels( $beans );
1411:     }
1412: 
1413:     /**
1414:      * Closes the database connection.
1415:      *
1416:      * @return void
1417:      */
1418:     public static function close()
1419:     {
1420:         if ( isset( self::$adapter ) ) {
1421:             self::$adapter->close();
1422:         }
1423:     }
1424: 
1425:     /**
1426:      * Simple convenience function, returns ISO date formatted representation
1427:      * of $time.
1428:      *
1429:      * @param mixed $time UNIX timestamp
1430:      *
1431:      * @return string
1432:      */
1433:     public static function isoDate( $time = NULL )
1434:     {
1435:         if ( !$time ) {
1436:             $time = time();
1437:         }
1438: 
1439:         return @date( 'Y-m-d', $time );
1440:     }
1441: 
1442:     /**
1443:      * Simple convenience function, returns ISO date time
1444:      * formatted representation
1445:      * of $time.
1446:      *
1447:      * @param mixed $time UNIX timestamp
1448:      *
1449:      * @return string
1450:      */
1451:     public static function isoDateTime( $time = NULL )
1452:     {
1453:         if ( !$time ) $time = time();
1454:         return @date( 'Y-m-d H:i:s', $time );
1455:     }
1456: 
1457:     /**
1458:      * Optional accessor for neat code.
1459:      * Sets the database adapter you want to use.
1460:      *
1461:      * @param Adapter $adapter Database Adapter for facade to use
1462:      *
1463:      * @return void
1464:      */
1465:     public static function setDatabaseAdapter( Adapter $adapter )
1466:     {
1467:         self::$adapter = $adapter;
1468:     }
1469: 
1470:     /**
1471:      * Optional accessor for neat code.
1472:      * Sets the database adapter you want to use.
1473:      *
1474:      * @param QueryWriter $writer Query Writer instance for facade to use
1475:      *
1476:      * @return void
1477:      */
1478:     public static function setWriter( QueryWriter $writer )
1479:     {
1480:         self::$writer = $writer;
1481:     }
1482: 
1483:     /**
1484:      * Optional accessor for neat code.
1485:      * Sets the database adapter you want to use.
1486:      *
1487:      * @param OODB $redbean Object Database for facade to use
1488:      */
1489:     public static function setRedBean( OODB $redbean )
1490:     {
1491:         self::$redbean = $redbean;
1492:     }
1493: 
1494:     /**
1495:      * Optional accessor for neat code.
1496:      * Sets the database adapter you want to use.
1497:      *
1498:      * @return DBAdapter
1499:      */
1500:     public static function getDatabaseAdapter()
1501:     {
1502:         return self::$adapter;
1503:     }
1504: 
1505:     /**
1506:      * In case you use PDO (which is recommended and the default but not mandatory, hence
1507:      * the database adapter), you can use this method to obtain the PDO object directly.
1508:      * This is a convenience method, it will do the same as:
1509:      *
1510:      * <code>
1511:      * R::getDatabaseAdapter()->getDatabase()->getPDO();
1512:      * </code>
1513:      *
1514:      * If the PDO object could not be found, for whatever reason, this method
1515:      * will return NULL instead.
1516:      *
1517:      * @return NULL|PDO
1518:      */
1519:     public static function getPDO()
1520:     {
1521:         $databaseAdapter = self::getDatabaseAdapter();
1522:         if ( is_null( $databaseAdapter ) ) return NULL;
1523:         $database = $databaseAdapter->getDatabase();
1524:         if ( is_null( $database ) ) return NULL;
1525:         if ( !method_exists( $database, 'getPDO' ) ) return NULL;
1526:         return $database->getPDO();
1527:     }
1528: 
1529:     /**
1530:      * Returns the current duplication manager instance.
1531:      *
1532:      * @return DuplicationManager
1533:      */
1534:     public static function getDuplicationManager()
1535:     {
1536:         return self::$duplicationManager;
1537:     }
1538: 
1539:     /**
1540:      * Optional accessor for neat code.
1541:      * Sets the database adapter you want to use.
1542:      *
1543:      * @return QueryWriter
1544:      */
1545:     public static function getWriter()
1546:     {
1547:         return self::$writer;
1548:     }
1549: 
1550:     /**
1551:      * Optional accessor for neat code.
1552:      * Sets the database adapter you want to use.
1553:      *
1554:      * @return OODB
1555:      */
1556:     public static function getRedBean()
1557:     {
1558:         return self::$redbean;
1559:     }
1560: 
1561:     /**
1562:      * Returns the toolbox currently used by the facade.
1563:      * To set the toolbox use R::setup() or R::configureFacadeWithToolbox().
1564:      * To create a toolbox use Setup::kickstart(). Or create a manual
1565:      * toolbox using the ToolBox class.
1566:      *
1567:      * @return ToolBox
1568:      */
1569:     public static function getToolBox()
1570:     {
1571:         return self::$toolbox;
1572:     }
1573: 
1574:     /**
1575:      * Mostly for internal use, but might be handy
1576:      * for some users.
1577:      * This returns all the components of the currently
1578:      * selected toolbox.
1579:      *
1580:      * Returns the components in the following order:
1581:      *
1582:      * # OODB instance (getRedBean())
1583:      * # Database Adapter
1584:      * # Query Writer
1585:      * # Toolbox itself
1586:      *
1587:      * @return array
1588:      */
1589:     public static function getExtractedToolbox()
1590:     {
1591:         return array( self::$redbean, self::$adapter, self::$writer, self::$toolbox );
1592:     }
1593: 
1594:     /**
1595:      * Facade method for AQueryWriter::renameAssociation()
1596:      *
1597:      * @param string|array $from
1598:      * @param string       $to
1599:      *
1600:      * @return void
1601:      */
1602:     public static function renameAssociation( $from, $to = NULL )
1603:     {
1604:         AQueryWriter::renameAssociation( $from, $to );
1605:     }
1606: 
1607:     /**
1608:      * Little helper method for Resty Bean Can server and others.
1609:      * Takes an array of beans and exports each bean.
1610:      * Unlike exportAll this method does not recurse into own lists
1611:      * and shared lists, the beans are exported as-is, only loaded lists
1612:      * are exported.
1613:      *
1614:      * @param array $beans beans
1615:      *
1616:      * @return array
1617:      */
1618:     public static function beansToArray( $beans )
1619:     {
1620:         $list = array();
1621:         foreach( $beans as $bean ) $list[] = $bean->export();
1622:         return $list;
1623:     }
1624: 
1625:     /**
1626:      * Sets the error mode for FUSE.
1627:      * What to do if a FUSE model method does not exist?
1628:      * You can set the following options:
1629:      *
1630:      * * OODBBean::C_ERR_IGNORE (default), ignores the call, returns NULL
1631:      * * OODBBean::C_ERR_LOG, logs the incident using error_log
1632:      * * OODBBean::C_ERR_NOTICE, triggers a E_USER_NOTICE
1633:      * * OODBBean::C_ERR_WARN, triggers a E_USER_WARNING
1634:      * * OODBBean::C_ERR_EXCEPTION, throws an exception
1635:      * * OODBBean::C_ERR_FUNC, allows you to specify a custom handler (function)
1636:      * * OODBBean::C_ERR_FATAL, triggers a E_USER_ERROR
1637:      *
1638:      * <code>
1639:      * Custom handler method signature: handler( array (
1640:      *  'message' => string
1641:      *  'bean' => OODBBean
1642:      *  'method' => string
1643:      * ) )
1644:      * </code>
1645:      *
1646:      * This method returns the old mode and handler as an array.
1647:      *
1648:      * @param integer       $mode mode, determines how to handle errors
1649:      * @param callable|NULL $func custom handler (if applicable)
1650:      *
1651:      * @return array
1652:      */
1653:     public static function setErrorHandlingFUSE( $mode, $func = NULL )
1654:     {
1655:         return OODBBean::setErrorHandlingFUSE( $mode, $func );
1656:     }
1657: 
1658:     /**
1659:      * Simple but effective debug function.
1660:      * Given a one or more beans this method will
1661:      * return an array containing first part of the string
1662:      * representation of each item in the array.
1663:      *
1664:      * @param OODBBean|array $data either a bean or an array of beans
1665:      *
1666:      * @return array
1667:      */
1668:     public static function dump( $data )
1669:     {
1670:         return Dump::dump( $data );
1671:     }
1672: 
1673:     /**
1674:      * Binds an SQL function to a column.
1675:      * This method can be used to setup a decode/encode scheme or
1676:      * perform UUID insertion. This method is especially useful for handling
1677:      * MySQL spatial columns, because they need to be processed first using
1678:      * the asText/GeomFromText functions.
1679:      *
1680:      * Example:
1681:      *
1682:      * <code>
1683:      * R::bindFunc( 'read', 'location.point', 'asText' );
1684:      * R::bindFunc( 'write', 'location.point', 'GeomFromText' );
1685:      * </code>
1686:      *
1687:      * Passing NULL as the function will reset (clear) the function
1688:      * for this column/mode.
1689:      *
1690:      * @param string $mode     mode for function: i.e. read or write
1691:      * @param string $field    field (table.column) to bind function to
1692:      * @param string $function SQL function to bind to specified column
1693:      *
1694:      * @return void
1695:      */
1696:     public static function bindFunc( $mode, $field, $function )
1697:     {
1698:         self::$redbean->bindFunc( $mode, $field, $function );
1699:     }
1700: 
1701:     /**
1702:      * Sets global aliases.
1703:      * Registers a batch of aliases in one go. This works the same as
1704:      * fetchAs and setAutoResolve but explicitly. For instance if you register
1705:      * the alias 'cover' for 'page' a property containing a reference to a
1706:      * page bean called 'cover' will correctly return the page bean and not
1707:      * a (non-existant) cover bean.
1708:      *
1709:      * <code>
1710:      * R::aliases( array( 'cover' => 'page' ) );
1711:      * $book = R::dispense( 'book' );
1712:      * $page = R::dispense( 'page' );
1713:      * $book->cover = $page;
1714:      * R::store( $book );
1715:      * $book = $book->fresh();
1716:      * $cover = $book->cover;
1717:      * echo $cover->getMeta( 'type' ); //page
1718:      * </code>
1719:      *
1720:      * The format of the aliases registration array is:
1721:      *
1722:      * {alias} => {actual type}
1723:      *
1724:      * In the example above we use:
1725:      *
1726:      * cover => page
1727:      *
1728:      * From that point on, every bean reference to a cover
1729:      * will return a 'page' bean. Note that with autoResolve this
1730:      * feature along with fetchAs() is no longer very important, although
1731:      * relying on explicit aliases can be a bit faster.
1732:      *
1733:      * @param array $list list of global aliases to use
1734:      *
1735:      * @return void
1736:      */
1737:     public static function aliases( $list )
1738:     {
1739:         OODBBean::aliases( $list );
1740:     }
1741: 
1742:     /**
1743:      * Tries to find a bean matching a certain type and
1744:      * criteria set. If no beans are found a new bean
1745:      * will be created, the criteria will be imported into this
1746:      * bean and the bean will be stored and returned.
1747:      * If multiple beans match the criteria only the first one
1748:      * will be returned.
1749:      *
1750:      * @param string $type type of bean to search for
1751:      * @param array  $like criteria set describing the bean to search for
1752:      *
1753:      * @return OODBBean
1754:      */
1755:     public static function findOrCreate( $type, $like = array() )
1756:     {
1757:         return self::$finder->findOrCreate( $type, $like );
1758:     }
1759: 
1760:     /**
1761:      * Tries to find beans matching the specified type and
1762:      * criteria set.
1763:      *
1764:      * If the optional additional SQL snippet is a condition, it will
1765:      * be glued to the rest of the query using the AND operator.
1766:      *
1767:      * @param string $type type of bean to search for
1768:      * @param array  $like optional criteria set describing the bean to search for
1769:      * @param string $sql  optional additional SQL for sorting
1770:      *
1771:      * @return array
1772:      */
1773:     public static function findLike( $type, $like = array(), $sql = '' )
1774:     {
1775:         return self::$finder->findLike( $type, $like, $sql );
1776:     }
1777: 
1778:     /**
1779:      * Starts logging queries.
1780:      * Use this method to start logging SQL queries being
1781:      * executed by the adapter.
1782:      *
1783:      * @note you cannot use R::debug and R::startLogging
1784:      * at the same time because R::debug is essentially a
1785:      * special kind of logging.
1786:      *
1787:      * @return void
1788:      */
1789:     public static function startLogging()
1790:     {
1791:         self::debug( TRUE, RDefault::C_LOGGER_ARRAY );
1792:     }
1793: 
1794:     /**
1795:      * Stops logging, comfortable method to stop logging of queries.
1796:      *
1797:      * @return void
1798:      */
1799:     public static function stopLogging()
1800:     {
1801:         self::debug( FALSE );
1802:     }
1803: 
1804:     /**
1805:      * Returns the log entries written after the startLogging.
1806:      *
1807:      * @return array
1808:      */
1809:     public static function getLogs()
1810:     {
1811:         return self::getLogger()->getLogs();
1812:     }
1813: 
1814:     /**
1815:      * Resets the Query counter.
1816:      *
1817:      * @return integer
1818:      */
1819:     public static function resetQueryCount()
1820:     {
1821:         self::$adapter->getDatabase()->resetCounter();
1822:     }
1823: 
1824:     /**
1825:      * Returns the number of SQL queries processed.
1826:      *
1827:      * @return integer
1828:      */
1829:     public static function getQueryCount()
1830:     {
1831:         return self::$adapter->getDatabase()->getQueryCount();
1832:     }
1833: 
1834:     /**
1835:      * Returns the current logger instance being used by the
1836:      * database object.
1837:      *
1838:      * @return Logger
1839:      */
1840:     public static function getLogger()
1841:     {
1842:         return self::$adapter->getDatabase()->getLogger();
1843:     }
1844: 
1845:     /**
1846:      * Alias for setAutoResolve() method on OODBBean.
1847:      * Enables or disables auto-resolving fetch types.
1848:      * Auto-resolving aliased parent beans is convenient but can
1849:      * be slower and can create infinite recursion if you
1850:      * used aliases to break cyclic relations in your domain.
1851:      *
1852:      * @param boolean $automatic TRUE to enable automatic resolving aliased parents
1853:      *
1854:      * @return void
1855:      */
1856:     public static function setAutoResolve( $automatic = TRUE )
1857:     {
1858:         OODBBean::setAutoResolve( (boolean) $automatic );
1859:     }
1860: 
1861:     /**
1862:      * Dynamically extends the facade with a plugin.
1863:      * Using this method you can register your plugin with the facade and then
1864:      * use the plugin by invoking the name specified plugin name as a method on
1865:      * the facade.
1866:      *
1867:      * Usage:
1868:      *
1869:      * <code>
1870:      * R::ext( 'makeTea', function() { ... }  );
1871:      * </code>
1872:      *
1873:      * Now you can use your makeTea plugin like this:
1874:      *
1875:      * <code>
1876:      * R::makeTea();
1877:      * </code>
1878:      *
1879:      * @param string   $pluginName name of the method to call the plugin
1880:      * @param callable $callable   a PHP callable
1881:      *
1882:      * @return void
1883:      */
1884:     public static function ext( $pluginName, $callable )
1885:     {
1886:         if ( !ctype_alnum( $pluginName ) ) {
1887:             throw new RedException( 'Plugin name may only contain alphanumeric characters.' );
1888:         }
1889:         self::$plugins[$pluginName] = $callable;
1890:     }
1891: 
1892:     /**
1893:      * Call static for use with dynamic plugins. This magic method will
1894:      * intercept static calls and route them to the specified plugin.
1895:      *
1896:      * @param string $pluginName name of the plugin
1897:      * @param array  $params     list of arguments to pass to plugin method
1898:      *
1899:      * @return mixed
1900:      */
1901:     public static function __callStatic( $pluginName, $params )
1902:     {
1903:         if ( !ctype_alnum( $pluginName) ) {
1904:             throw new RedException( 'Plugin name may only contain alphanumeric characters.' );
1905:         }
1906:         if ( !isset( self::$plugins[$pluginName] ) ) {
1907:             throw new RedException( 'Plugin \''.$pluginName.'\' does not exist, add this plugin using: R::ext(\''.$pluginName.'\')' );
1908:         }
1909:         return call_user_func_array( self::$plugins[$pluginName], $params );
1910:     }
1911: }
1912: 
1913: 
API documentation generated by ApiGen