install
[ class tree: install ] [ index: install ] [ all elements ]

Source for file BitInstaller.php

Documentation is available at BitInstaller.php

  1. <?php
  2. /**
  3.  * @version $Header$
  4.  * @package install
  5.  */
  6.  
  7. /**
  8.  * @package install
  9.  */
  10. class BitInstaller extends BitSystem {
  11.  
  12.     /**
  13.      * mPackageUpgrades
  14.      *
  15.      * @var array 
  16.      * @access public
  17.      */
  18.     var $mPackageUpgrades = array();
  19.  
  20.     /**
  21.      * mRequirements
  22.      *
  23.      * @var array 
  24.      * @access public
  25.      */
  26.     var $mRequirements = array();
  27.  
  28.     /**
  29.      * Initiolize BitInstaller
  30.      * @access public
  31.      */
  32.     function BitInstaller() {
  33.         parent::__construct();
  34.         $this->getWebServerUid();
  35.     }
  36.  
  37.     /**
  38.      * loadAllUpgradeFiles load upgrade files from all packages that are installed
  39.      *
  40.      * @access public
  41.      * @return void 
  42.      */
  43.     function loadAllUpgradeFiles() {
  44.         foreach( array_keys( $this->mPackages ) as $pkg ) {
  45.             $this->loadUpgradeFiles( $pkg );
  46.         }
  47.     }
  48.  
  49.     /**
  50.      * Minimal login just for install in case users tables have been modified
  51.      * 
  52.      * @access public
  53.      * @return void 
  54.      */
  55.     function login( $pLogin, $pPassword, $pChallenge=NULL, $pResponse=NULL ) {
  56.         global $gBitUser;
  57.  
  58.         $isvalid = false;
  59.  
  60.         $loginCol = strpos( $pLogin, '@' ) ? 'email' : 'login';
  61.  
  62.         if( $gBitUser->validate( $pLogin, $pPassword, $pChallenge, $pResponse ) ) {
  63.             $userInfo = $gBitUser->getUserInfo( array( $loginCol => $pLogin ) );
  64.  
  65.             if( $userInfo['user_id'] != ANONYMOUS_USER_ID ) {
  66.                 // User is valid and not due to change pass..
  67.                 $gBitUser->mUserId = $userInfo['user_id'];
  68.                 $gBitUser->mInfo = $userInfo;
  69.                 $gBitUser->loadPermissions( TRUE );
  70.  
  71.                 $sessionId = session_id();
  72.                 $gBitUser->sendSessionCookie( $sessionId );
  73.                 $gBitUser->updateSession( $sessionId );
  74.             }
  75.         }
  76.  
  77.         return $gBitUser->isAdmin();
  78.     }
  79.  
  80.     /**
  81.      * loadUpgradeFiles This will load all files in the dir <pckage>/admin/upgrades/<version>.php with a version greater than the one installed
  82.      *
  83.      * @param array $pPackage 
  84.      * @access public
  85.      * @return void 
  86.      */
  87.     function loadUpgradeFiles( $pPackage ) {
  88.         if( !empty( $pPackage )) {
  89.             $dir = constant( strtoupper( $pPackage )."_PKG_PATH" )."admin/upgrades/";
  90.             if( $this->isPackageActive( $pPackage ) && is_dir( $dir ) && $upDir = opendir( $dir )) {
  91.                 while( FALSE !== ( $file = readdir( $upDir ))) {
  92.                     if( is_file( $dir.$file )) {
  93.                         $upVersion = str_replace( ".php", "", $file );
  94.                         // we only want to load files of versions that are greater than is installed
  95.                         if( $this->validateVersion( $upVersion ) && version_compare( $this->getVersion( $pPackage ), $upVersion, '<' )) {
  96.                             include_once( $dir.$file );
  97.                         }
  98.                     }
  99.                 }
  100.             }
  101.         }
  102.     }
  103.  
  104.     /**
  105.      * registerPackageUpgrade
  106.      *
  107.      * @param array $pParams Hash of information about upgrade
  108.      * @param string $pParams[package] Name of package that is upgrading
  109.      * @param string $pParams[version] Version of this upgrade
  110.      * @param string $pParams[description] Description of what the upgrade does
  111.      * @param string $pParams[post_upgrade] Textual note of stuff that needs to be observed after the upgrade
  112.      * @param array $pUpgradeHash Hash of update rules. See existing upgrades on how this works.
  113.      * @access public
  114.      * @return void 
  115.      */
  116.     function registerPackageUpgrade( $pParams, $pUpgradeHash = array() ) {
  117.         if( $this->verifyPackageUpgrade( $pParams )) {
  118.             $this->registerPackageVersion( $pParams['package'], $pParams['version'] );
  119.             $this->mPackageUpgrades[$pParams['package']][$pParams['version']]            = $pParams;
  120.             $this->mPackageUpgrades[$pParams['package']][$pParams['version']]['upgrade'] = $pUpgradeHash;
  121.  
  122.             // sort everything for a nice display
  123.             ksort( $this->mPackageUpgrades );
  124.             uksort( $this->mPackageUpgrades[$pParams['package']], 'version_compare' );
  125.         }
  126.     }
  127.  
  128.     /**
  129.      * verifyPackageUpgrade
  130.      *
  131.      * @param array $pParams Hash of information about upgrade
  132.      * @param string $pParams[package] Name of package that is upgrading
  133.      * @param string $pParams[version] Version of this upgrade
  134.      * @param string $pParams[description] Description of what the upgrade does
  135.      * @param string $pParams[post_upgrade] Textual note of stuff that needs to be observed after the upgrade
  136.      * @access public
  137.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  138.      */
  139.     function verifyPackageUpgrade( &$pParams ) {
  140.         if( empty( $pParams['package'] )) {
  141.             $this->mErrors['package'] = "Please provide a valid package name.";
  142.         } else {
  143.             $pParams['package'] = strtolower( $pParams['package'] );
  144.         }
  145.  
  146.         if( empty( $pParams['version'] ) || !$this->validateVersion( $pParams['version'] )) {
  147.             $this->mErrors['version'] = "Please provide a valid version number.";
  148.         } elseif( empty( $this->mErrors ) && !empty( $this->mPackageUpgrades[$pParams['package']][$pParams['version']] )) {
  149.             $this->mErrors['version'] = "Please make sure you use a unique version number to register your new database changes.";
  150.         }
  151.  
  152.         if( empty( $pParams['description'] )) {
  153.             $this->mErrors['description'] = "Please add a brief description of what this upgrade is all about.";
  154.         }
  155.  
  156.         // since this should only show up when devs are working, we'll simply display the output:
  157.         if( !empty( $this->mErrors )) {
  158.             vd( $this->mErrors );
  159.             bt();
  160.         }
  161.  
  162.         return( count( $this->mErrors ) == 0 );
  163.     }
  164.  
  165.     /**
  166.      * registerUpgrade
  167.      *
  168.      * @param array $pPackage 
  169.      * @param array $pUpgradeHash 
  170.      * @access public
  171.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  172.      */
  173.     function registerUpgrade( $pPackage, $pUpgradeHash ) {
  174.         $pPackage = strtolower( $pPackage ); // lower case for uniformity
  175.         if( !empty( $pUpgradeHash ) ) {
  176.             $this->mUpgrades[$pPackage] = $pUpgradeHash;
  177.         }
  178.     }
  179.  
  180.     /**
  181.      * display
  182.      *
  183.      * @param string $pTemplate 
  184.      * @param string $pBrowserTitle 
  185.      * @access public
  186.      * @return void 
  187.      */
  188.     function in_display( $pPackage, $pTemplate ) {
  189.         header( 'Content-Type: text/html; charset=utf-8' );
  190.         if( ini_get( 'safe_mode' ) && ini_get( 'safe_mode_gid' )) {
  191.             umask( 0007 );
  192.         }
  193.         // force the session to close *before* displaying. Why? Note this very important comment from http://us4.php.net/exec
  194.         session_write_close();
  195.  
  196.         if( !empty( $pPackage ) ) {
  197.             $this->setBrowserTitle( $pPackage );
  198.         }
  199.         global $gBitSmarty;
  200.         $gBitSmarty->verifyCompileDir();
  201.         $gBitSmarty->display( $pTemplate );
  202.     }
  203.  
  204.     /**
  205.      * isInstalled
  206.      *
  207.      * @access public
  208.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  209.      */
  210.     function isInstalled( $pPackage = 'kernel' ) {
  211.         return( !empty( $this->mPackages[$pPackage]['installed'] ));
  212.     }
  213.  
  214.     /**
  215.      * getWebServerUid set global wwwuser and wwwgroup
  216.      *
  217.      * @access public
  218.      * @return void 
  219.      */
  220.     function getWebServerUid() {
  221.         global $wwwuser, $wwwgroup;
  222.         $wwwuser = $wwwgroup = '';
  223.  
  224.         if( is_windows() ) {
  225.             $wwwuser = 'SYSTEM';
  226.             $wwwgroup = 'SYSTEM';
  227.         }
  228.  
  229.         if( function_exists( 'posix_getuid' )) {
  230.             $user = @posix_getpwuid( @posix_getuid() );
  231.             $group = @posix_getpwuid( @posix_getgid() );
  232.             $wwwuser = $user ? $user['name'] : false;
  233.             $wwwgroup = $group ? $group['name'] : false;
  234.         }
  235.  
  236.         if( !$wwwuser ) {
  237.             $wwwuser = 'nobody (or the user account the web server is running under)';
  238.         }
  239.  
  240.         if( !$wwwgroup ) {
  241.             $wwwgroup = 'nobody (or the group account the web server is running under)';
  242.         }
  243.     }
  244.  
  245.     /**
  246.      * getTablePrefix
  247.      *
  248.      * @access public
  249.      * @return database adjusted table prefix
  250.      */
  251.     function getTablePrefix() {
  252.         global $gBitDbType;
  253.         $ret = BIT_DB_PREFIX;
  254.         // avoid errors in ADONewConnection() (wrong database driver etc...)
  255.         // strip out some schema stuff
  256.         switch( $gBitDbType ) {
  257.             case "sybase":
  258.                 // avoid database change messages
  259.                 ini_set('sybct.min_server_severity', '11');
  260.                 break;
  261.             case "oci8":
  262.             case "postgres":
  263.                 // Do a little prep work for postgres, no break, cause we want default case too
  264.                 if( preg_match( '/\./', $ret ) ) {
  265.                     // Assume we want to dump in a schema, so set the search path and nuke the prefix here.
  266.                     $schema = preg_replace( '/`/', '"', substr( $ret, 0, strpos( $ret, '.' )) );
  267.                     $quote = strpos( $schema, '"' );
  268.                     if( $quote !== 0 ) {
  269.                         $schema = '"'.$schema;
  270.                     }
  271.                     // set scope to current schema
  272.                     $result = $this->mDb->query( "SET search_path TO $schema" );
  273.                     // return everything after the prefix
  274.                     $ret = substr( BIT_DB_PREFIX, strrpos( BIT_DB_PREFIX, '`' ) + 1 );
  275.                 }
  276.                 break;
  277.         }
  278.         return $ret;
  279.     }
  280.  
  281.     /**
  282.      * upgradePackage
  283.      *
  284.      * @param array $pPackage 
  285.      * @access public
  286.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  287.      */
  288.     function upgradePackage( $pPackage ) {
  289.         if( !empty( $pPackage ) && !empty( $this->mUpgrades[$pPackage] )) {
  290.             return( $this->applyUpgrade( $pPackage, $this->mUpgrades[$pPackage] ));
  291.         }
  292.     }
  293.  
  294.     /**
  295.      * upgradePackageVersion
  296.      *
  297.      * @param array $pPackage 
  298.      * @param array $pVersion 
  299.      * @access public
  300.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  301.      */
  302.     function upgradePackageVersions( $pPackage ) {
  303.         if( !empty( $pPackage ) && !empty( $this->mPackageUpgrades[$pPackage] )) {
  304.             // make sure everything is in the right order
  305.             uksort( $this->mPackageUpgrades[$pPackage], 'upgrade_version_sort' );
  306.  
  307.             foreach( array_keys( $this->mPackageUpgrades[$pPackage] ) as $version ) {
  308.                 // version we are upgrading from
  309.                 $this->mPackageUpgrades[$pPackage][$version]['from_version'] = $this->getVersion( $pPackage );
  310.  
  311.                 // apply upgrade
  312.                 $errors[$version] = $this->applyUpgrade( $pPackage, $this->mPackageUpgrades[$pPackage][$version]['upgrade'] );
  313.                 if( !empty( $errors[$version] )) {
  314.                     return $errors;
  315.                 } else {
  316.                     // if the upgrade ended without incidence, we store the package version.
  317.                     // this way any successfully applied upgrade can only be applied once.
  318.                     $this->storeVersion( $pPackage, $version );
  319.                 }
  320.             }
  321.         }
  322.  
  323.         return NULL;
  324.     }
  325.  
  326.     /**
  327.      * applyUpgrade
  328.      *
  329.      * @param array $pPackage 
  330.      * @param array $pUpgradeHash 
  331.      * @access public
  332.      * @return empty array on success, array with errors on failure
  333.      */
  334.     function applyUpgrade( $pPackage, $pUpgradeHash ) {
  335.         global $gBitDb, $gBitDbType;
  336.         $ret = array();
  337.  
  338.         if( !empty( $pUpgradeHash ) && is_array( $pUpgradeHash )) {
  339.             // set table prefixes and handle special case of sequence prefixes
  340.             $schemaQuote = strrpos( BIT_DB_PREFIX, '`' );
  341.             $sequencePrefix = ( $schemaQuote ? substr( BIT_DB_PREFIX,  $schemaQuote + 1 ) : BIT_DB_PREFIX );
  342.             $tablePrefix = $this->getTablePrefix();
  343.             $dict = NewDataDictionary( $gBitDb->mDb );
  344.             $failedcommands = array();
  345.  
  346.             for( $i = 0; $i < count( $pUpgradeHash ); $i++ ) {
  347.                 if( !is_array( $pUpgradeHash[$i] ) ) {
  348.                     vd( "[$pPackage][$i] is NOT an array" );
  349.                     vd( $pUpgradeHash[$i] );
  350.                     bt();
  351.                     die;
  352.                 }
  353.  
  354.                 $type = key( $pUpgradeHash[$i] );
  355.                 $step = &$pUpgradeHash[$i][$type];
  356.  
  357.                 switch( $type ) {
  358.                     case 'DATADICT':
  359.                         for( $j = 0; $j < count( $step ); $j++ ) {
  360.                             $dd = &$step[$j];
  361.                             switch( key( $dd ) ) {
  362.                                 case 'CREATE':
  363.                                     foreach( $dd as $create ) {
  364.                                         foreach( array_keys( $create ) as $tableName ) {
  365.                                             $completeTableName = $tablePrefix.$tableName;
  366.                                             $sql = $dict->CreateTableSQL( $completeTableName, $create[$tableName], 'REPLACE' );
  367.                                             if( $sql && ( $dict->ExecuteSQLArray( $sql, FALSE ) > 0 ) ) {
  368.                                             } else {
  369.                                                 $errors[] = 'Failed to create '.$completeTableName;
  370.                                                 $failedcommands[] = implode( " ", $sql );
  371.                                             }
  372.                                         }
  373.                                     }
  374.                                     break;
  375.                                 case 'ALTER':
  376.                                     foreach( $dd as $alter ) {
  377.                                         foreach( array_keys( $alter ) as $tableName ) {
  378.                                             $completeTableName = $tablePrefix.$tableName;
  379.                                             $this->mDb->convertQuery( $completeTableName );
  380.                                             foreach( $alter[$tableName] as $from => $flds ) {
  381.                                                 if( is_string( $flds )) {
  382.                                                     $sql = $dict->ChangeTableSQL( $completeTableName, $flds );
  383.                                                 } else {
  384.                                                     $sql = $dict->ChangeTableSQL( $completeTableName, array( $flds ));
  385.                                                 }
  386.  
  387.                                                 if( $sql ) {
  388.                                                     for( $sqlIdx = 0; $sqlIdx < count( $sql ); $sqlIdx++ ) {
  389.                                                         $this->mDb->convertQuery( $sqlFoo );
  390.                                                     }
  391.                                                 }
  392.  
  393.                                                 if( $sql && $dict->ExecuteSQLArray( $sql, FALSE ) > 0 ) {
  394.                                                 } else {
  395.                                                     $errors[] = 'Failed to alter '.$completeTableName.' -> '.$alter[$tableName];
  396.                                                     $failedcommands[] = implode( " ", $sql );
  397.                                                 }
  398.                                             }
  399.                                         }
  400.                                     }
  401.                                     break;
  402.                                 case 'RENAMETABLE':
  403.                                     foreach( $dd as $rename ) {
  404.                                         foreach( array_keys( $rename ) as $tableName ) {
  405.                                             $completeTableName = $tablePrefix.$tableName;
  406.                                             if( $sql = @$dict->RenameTableSQL( $completeTableName, $tablePrefix.$rename[$tableName] ) ) {
  407.                                                 foreach( $sql AS $query ) {
  408.                                                     $this->mDb->query( $query );
  409.                                                 }
  410.                                             } else {
  411.                                                 $errors[] = 'Failed to rename table '.$completeTableName.'.'.$rename[$tableName][0].' to '.$rename[$tableName][1];
  412.                                                 $failedcommands[] = implode( " ", $sql );
  413.                                             }
  414.                                         }
  415.                                     }
  416.                                     break;
  417.                                 case 'RENAMECOLUMN':
  418.                                     foreach( $dd as $rename ) {
  419.                                         foreach( array_keys( $rename ) as $tableName ) {
  420.                                             $completeTableName = $tablePrefix.$tableName;
  421.                                             foreach( $rename[$tableName] as $from => $flds ) {
  422.                                                 // MySQL needs the fields string, others do not.
  423.                                                 // see http://phplens.com/lens/adodb/docs-datadict.htm
  424.                                                 $to = substr( $flds, 0, strpos( $flds, ' ') );
  425.                                                 if( $sql = @$dict->RenameColumnSQL( $completeTableName, $from, $to, $flds ) ) {
  426.                                                     foreach( $sql AS $query ) {
  427.                                                         $this->mDb->query( $query );
  428.                                                     }
  429.                                                 } else {
  430.                                                     $errors[] = 'Failed to rename column '.$completeTableName.'.'.$rename[$tableName][0].' to '.$rename[$tableName][1];
  431.                                                     $failedcommands[] = implode( " ", $sql );
  432.                                                 }
  433.                                             }
  434.                                         }
  435.                                     }
  436.                                     break;
  437.                                 case 'CREATESEQUENCE':
  438.                                     foreach( $dd as $create ) {
  439.                                         foreach( $create as $sequence ) {
  440.                                             $this->mDb->CreateSequence( $sequencePrefix.$sequence );
  441.                                         }
  442.                                     }
  443.                                     break;
  444.                                 case 'RENAMESEQUENCE':
  445.                                     foreach( $dd as $rename ) {
  446.                                         foreach( $rename as $from => $to ) {
  447.                                             if( $gBitDbType != 'mysql' || $this->mDb->tableExists( $tablePrefix.$from ) ) {
  448.                                                 if( $id = $this->mDb->GenID( $from ) ) {
  449.                                                     $this->mDb->DropSequence( $sequencePrefix.$from );
  450.                                                     $this->mDb->CreateSequence( $sequencePrefix.$to, $id );
  451.                                                 } else {
  452.                                                     $errors[] = 'Failed to rename sequence '.$sequencePrefix.$from.' to '.$sequencePrefix.$to;
  453.                                                     $failedcommands[] = implode( " ", $sql );
  454.                                                 }
  455.                                             } else {
  456.                                                 $this->mDb->CreateSequence( $sequencePrefix.$to, $pUpgradeHash['sequences'][$to]['start'] );
  457.                                             }
  458.                                         }
  459.                                     }
  460.                                     break;
  461.                                 case 'DROPSEQUENCE':
  462.                                     foreach( $dd as $drop ) {
  463.                                         foreach( $drop as $sequence ) {
  464.                                             $this->mDb->DropSequence( $sequencePrefix.$sequence );
  465.                                         }
  466.                                     }
  467.                                     break;
  468.                                 case 'DROPCOLUMN':
  469.                                     foreach( $dd as $drop ) {
  470.                                         foreach( array_keys( $drop ) as $tableName ) {
  471.                                             $completeTableName = $tablePrefix.$tableName;
  472.                                             foreach( $drop[$tableName] as $col ) {
  473.                                                 if( $sql = $dict->DropColumnSQL( $completeTableName, $col ) ) {
  474.                                                     foreach( $sql AS $query ) {
  475.                                                         $this->mDb->query( $query );
  476.                                                     }
  477.                                                 } else {
  478.                                                     $errors[] = 'Failed to drop column '.$completeTableName;
  479.                                                     $failedcommands[] = implode( " ", $sql );
  480.                                                 }
  481.                                             }
  482.                                         }
  483.                                     }
  484.                                     break;
  485.                                 case 'DROPTABLE':
  486.                                     foreach( $dd as $drop ) {
  487.                                         foreach( $drop as $tableName ) {
  488.                                             $completeTableName = $tablePrefix.$tableName;
  489.                                             $sql = $dict->DropTableSQL( $completeTableName );
  490.                                             if( $sql && $dict->ExecuteSQLArray( $sql ) > 0 ) {
  491.                                             } else {
  492.                                                 $errors[] = 'Failed to drop table '.$completeTableName;
  493.                                                 $failedcommands[] = implode( " ", $sql );
  494.                                             }
  495.                                         }
  496.                                     }
  497.                                     break;
  498.                                 case 'CREATEINDEX':
  499.                                     foreach( $dd as $indices ) {
  500.                                         foreach( array_keys( $indices ) as $index ) {
  501.                                             $completeTableName = $tablePrefix.$indices[$index][0];
  502.                                             if( $sql = $dict->CreateIndexSQL( $index, $completeTableName, $indices[$index][1], $indices[$index][2] ) ) {
  503.                                                 foreach( $sql AS $query ) {
  504.                                                     $this->mDb->query( $query );
  505.                                                 }
  506.                                             } else {
  507.                                                 $errors[] = 'Failed to create index '.$index;
  508.                                                 $failedcommands[] = implode( " ", $sql );
  509.                                             }
  510.                                         }
  511.                                     }
  512.                                     break;
  513.                             }
  514.                         }
  515.                         if( !empty( $sql ) ) $sql = null;
  516.                         break;
  517.                     case 'QUERY':
  518.                         uksort( $step, 'upgrade_query_sort' );
  519.                         foreach( array_keys( $step ) as $dbType ) {
  520.                             if( $dbType == 'MYSQL' && preg_match( '/mysql/', $gBitDbType )) {
  521.                                 $sql = $step[$dbType];
  522.                                 unset( $step['SQL92'] );
  523.                             } elseif( $dbType == 'PGSQL' && preg_match( '/postgres/', $gBitDbType )) {
  524.                                 $sql = $step[$dbType];
  525.                                 unset( $step['SQL92'] );
  526.                             } elseif( $dbType == 'SQL92' && !empty( $step['SQL92'] )) {
  527.                                 $sql = $step[$dbType];
  528.                             }
  529.  
  530.                             if( !empty( $sql ) ) {
  531.                                 foreach( $sql as $query ) {
  532.                                     if( !$result = $this->mDb->query( $query )) {
  533.                                         $errors[] = 'Failed to execute SQL query';
  534.                                         $failedcommands[] = implode( " ", $sql );
  535.                                     }
  536.                                 }
  537.                                 $sql = NULL;
  538.                             }
  539.                         }
  540.                         break;
  541.                     case 'PHP':
  542.                         eval( $step );
  543.                         break;
  544.                     case 'POST':
  545.                         $postSql[] = $step;
  546.                         break;
  547.                 }
  548.             }
  549.  
  550.             // turn on features that are turned on
  551.             // legacy stuff
  552.             if( $this->isFeatureActive( 'feature_'.$pPackage )) {
  553.                 $this->storeConfig( 'package_'.$pPackage, 'y', KERNEL_PKG_NAME );
  554.             }
  555.  
  556.             if( !empty( $failedcommands )) {
  557.                 $ret['errors'] = $errors;
  558.                 $ret['failedcommands'] = $failedcommands;
  559.             }
  560.         }
  561.  
  562.         return $ret;
  563.     }
  564.  
  565.     /**
  566.      * identifyBlobs
  567.      *
  568.      * @param array $result 
  569.      * @access public
  570.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  571.      */
  572.     function identifyBlobs( $result ) {
  573.         $blobs = array();
  574.         //echo "FieldCount: ".$result->FieldCount()."\n";
  575.         for( $i = 0; $i < $result->FieldCount(); $i++ ) {
  576.             $field = $result->FetchField($i);
  577.             //echo $i."-".$field->name."-".$result->MetaType($field->type)."-".$field->max_length."\n";
  578.             // check for blobs
  579.             if(( $result->MetaType( $field->type ) == 'B' ) || ( $result->MetaType( $field->type )=='X' && $field->max_length >= 16777215 ))
  580.                 $blobs[] = $field->name;
  581.         }
  582.         return $blobs;
  583.     }
  584.  
  585.     /**
  586.      * convertBlobs enumerate blob fields and encoded
  587.      *
  588.      * @param string $gDb 
  589.      * @param array $res 
  590.      * @param array $blobs 
  591.      * @access public
  592.      * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  593.      */
  594.     function convertBlobs( $gDb, &$res, $blobs ) {
  595.         foreach( $blobs as $blob ) {
  596.             $res[$blob] = $gDb->dbByteEncode( $res[$blob] );
  597.         }
  598.     }
  599.  
  600.     /**
  601.      * hasAdminBlock
  602.      *
  603.      * @access public
  604.      * @return TRUE on success, FALSE on failure
  605.      * @deprecated i think this isn't used any more
  606.      */
  607.     function hasAdminBlock() {
  608.         deprecated( "i think this isn't used anymore." );
  609.         global $gBitUser;
  610.         // Let's find out if we are have admin perm or a root user
  611.         $ret = TRUE;
  612.         if( empty( $gBitUser ) || $gBitUser->isAdmin() ) {
  613.             $ret = FALSE;
  614.         } else {
  615.             // let's try to load up user_id - if successful, we know we have one.
  616.             $rootUser = new BitPermUser( 1 );
  617.             $rootUser->load();
  618.             if( !$rootUser->isValid() ) {
  619.                 $ret = FALSE;
  620.             }
  621.         }
  622.         return $ret;
  623.     }
  624. }
  625.  
  626. /**
  627.  * check_session_save_path
  628.  *
  629.  * @access public
  630.  * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  631.  */
  632.     global $errors;
  633.     if( ini_get( 'session.save_handler' ) == 'files' ) {
  634.         $save_path = ini_get( 'session.save_path' );
  635.  
  636.         if( !is_dir( $save_path )) {
  637.             $errors .= "The directory '$save_path' does not exist or PHP is not allowed to access it (check session.save_path or open_basedir entries in php.ini).\n";
  638.         } elseif( !bw_is_writeable( $save_path )) {
  639.             $errors .= "The directory '$save_path' is not writeable.\n";
  640.         }
  641.  
  642.         if( $errors ) {
  643.             $save_path = static::tempdir();
  644.  
  645.             if (is_dir($save_path) && bw_is_writeable($save_path)) {
  646.                 ini_set('session.save_path', $save_path);
  647.  
  648.                 $errors = '';
  649.             }
  650.         }
  651.     }
  652. }
  653.  
  654. /**
  655.  * makeConnection
  656.  *
  657.  * @param string $gBitDbType 
  658.  * @param string $gBitDbHost 
  659.  * @param string $gBitDbUser 
  660.  * @param string $gBitDbPassword 
  661.  * @param string $gBitDbName 
  662.  * @access public
  663.  * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  664.  */
  665. function makeConnection( $gBitDbType, $gBitDbHost, $gBitDbUser, $gBitDbPassword, $gBitDbName ) {
  666.     $gDb = &ADONewConnection( $gBitDbType );
  667.     if( !$gDb->Connect( $gBitDbHost, $gBitDbUser, $gBitDbPassword, $gBitDbName )) {
  668.         echo $gDb->ErrorMsg()."\n";
  669.         die;
  670.     }
  671.     global $gBitDbCaseSensitivity;
  672.     $gDb->mCaseSensitive = $gBitDbCaseSensitivity;
  673.     $gDb->SetFetchMode( ADODB_FETCH_ASSOC );
  674.     return $gDb;
  675. }
  676.  
  677. /**
  678.  * upgrade_package_sort sort packages before they are upgraded
  679.  *
  680.  * @param string $a 
  681.  * @param string $b 
  682.  * @access public
  683.  * @return numeric sort direction
  684.  */
  685. function upgrade_package_sort( $a, $b ) {
  686.     global $gBitInstaller;
  687.     $aa = $gBitInstaller->mPackages[$a];
  688.     $bb = $gBitInstaller->mPackages[$b];
  689.     if(( $aa['required'] && $bb['required'] ) || ( !$aa['required'] && !$bb['required'] )) {
  690.         return 0;
  691.     } elseif( $aa['required'] && !$bb['required'] ) {
  692.         return -1;
  693.     } elseif( !$aa['required'] && $bb['required'] ) {
  694.         return 1;
  695.     }
  696. }
  697.  
  698. /**
  699.  * upgrade_version_sort sort upgrades based on version number
  700.  *
  701.  * @param string $a 
  702.  * @param string $b 
  703.  * @access public
  704.  * @return numeric sort direction
  705.  */
  706. function upgrade_version_sort( $a, $b ) {
  707.     return version_compare( $a, $b, '>' );
  708. }
  709.  
  710. /**
  711.  * upgrade_query_sort sort queries that SQL92 queries are called last
  712.  *
  713.  * @param string $a 
  714.  * @param string $b 
  715.  * @access public
  716.  * @return numeric sort direction
  717.  */
  718. function upgrade_query_sort( $a, $b ) {
  719.     if( $a == 'SQL92' ) {
  720.         return 1;
  721.     } elseif( $b == 'SQL92' ) {
  722.         return -1;
  723.     } else {
  724.         return 0;
  725.     }
  726. }
  727.  
  728. ?>

Documentation generated on Wed, 29 Jul 2015 13:55:52 +0000 by phpDocumentor 1.5.0-lsces