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

Source for file liberty_lib.php

Documentation is available at liberty_lib.php

  1. <?php
  2. /**
  3.  * @package liberty
  4.  * @subpackage functions
  5.  */
  6.  
  7. // ================== Liberty Plugin Parsing ==================
  8. /**
  9.  * This crazy function will parse all the data plugin stuff found within any
  10.  * parsed text section
  11.  *
  12.  * @param array $pData Data to be parsed
  13.  * @access public
  14.  * @return void 
  15.  */
  16. function parse_data_plugins( &$pData, &$pReplace, &$pCommonObject, $pParseHash ) {
  17.     global $gLibertySystem, $gBitSystem;
  18.  
  19.     // note: $curlyTags[0] is the complete match, $curlyTags[1] is plugin name, $curlyTags[2] is plugin arguments
  20.     preg_match_all( "/\{\/?([A-Za-z0-9]+)([^\}]*)\}/", $pData, $curlyTags, PREG_OFFSET_CAPTURE );
  21.  
  22.     if( count( $curlyTags[0] ) ) {
  23.         // if TRUE, replace only CODE plugin, if false, replace all other plugins
  24.         $code_first = TRUE;
  25.  
  26.         // Process plugins in reverse order, so that nested plugins are handled from the inside out.
  27.         $i = count( $curlyTags[0] ) - 1;
  28.         while( $i >= 0 ) {
  29.             $plugin_start = $curlyTags[0][$i][0];
  30.             $plugin = $curlyTags[1][$i][0];
  31.             // Work out where the plugin starts. This can not be done using the
  32.             // positional data from $curlyTags since the position might have
  33.             // changed since the last cycle. We therefore need to determine the
  34.             // position direclty. - xing - Thursday Nov 01, 2007   22:55:10 CET
  35.             //$pos = $curlyTags[0][$i][1];
  36.             $pos = strpos( $pData, $plugin_start );
  37.             $dataTag = strtolower( $plugin );
  38.             // hush up the return of this in case someone uses curly braces to enclose text
  39.             $pluginInfo = $gLibertySystem->getPluginInfo( @$gLibertySystem->mDataTags[$dataTag] ) ;
  40.  
  41.             // only process a standalone unpaired tag or the start tag for a paired tag
  42.             if( empty( $paired_close_tag_seen[$dataTag] ) || $paired_close_tag_seen[$dataTag] == 0 ) {
  43.                 $paired_close_tag_seen[$dataTag] = 1;
  44.             } else {
  45.                 $paired_close_tag_seen[$dataTag] = 0;
  46.             }
  47.  
  48.             $is_opening_tag = FALSE;
  49.             if(( empty( $pluginInfo['requires_pair'] ) && ( strtolower( $plugin_start ) != '{/'. $dataTag . '}' ))
  50.                 || ( strpos( $plugin_start, ' ' ) > 0 )
  51.                 || ( strtolower( $plugin_start ) == '{'.$dataTag.'}' && !$paired_close_tag_seen[$dataTag] )
  52.             ) {
  53.                 $is_opening_tag = TRUE;
  54.             }
  55.  
  56.             if(
  57.                 // when in CODE parsing mode, replace only CODE plugins
  58.                 ( ( $code_first && ( $dataTag == 'code' ) )
  59.                     // when NOT in CODE parsing mode, replace all other plugins
  60.                     || ( !$code_first && ( $dataTag <> 'code' ) )
  61.                 )
  62.                 && !empty( $gLibertySystem->mDataTags[$dataTag] )
  63.                 && !empty( $pluginInfo )
  64.                 && ( $loadFunc = $gLibertySystem->getPluginFunction( $gLibertySystem->mDataTags[$dataTag], 'load_function' ) )
  65.                 && ( $is_opening_tag )
  66.             ) {
  67.  
  68.                 if( $pluginInfo['requires_pair'] ) {
  69.                     $plugin_end = '{/'.$plugin.'}';
  70.                     $pos_end = strpos( strtolower( $pData ), strtolower( $plugin_end ), $pos ); // where plugin data ends
  71.                     $plugin_end2 = '{'.$plugin.'}';
  72.                     $pos_end2 = strpos( strtolower( $pData ), strtolower( $plugin_end2 ), $pos + 1 ); // where plugin data ends
  73.  
  74.                     if( ( $pos_end2 > 0 && $pos_end2 > 0 && $pos_end2 < $pos_end ) || $pos_end === FALSE ) {
  75.                         $pos_end = $pos_end2;
  76.                         $plugin_end = $plugin_end2;
  77.                     }
  78.                 } else {
  79.                     $pos_end = $pos + strlen( $curlyTags[0][$i][0] );
  80.                     $plugin_end = '';
  81.                 }
  82.  
  83.                 // Extract the plugin data
  84.                 $plugin_data_len = $pos_end - $pos - strlen( $curlyTags[0][$i][0] );
  85.                 $plugin_data = substr( $pData, $pos + strlen( $plugin_start ), $plugin_data_len );
  86.  
  87.                 $arguments = array();
  88.                 // Construct argument list array
  89.                 $paramString = str_replace( '&gt;', '>', trim( $curlyTags[2][$i][0] ) );
  90.                 if( preg_match( '/^\(.*=>.*\)$/', $paramString ) ) {
  91.                     $paramString = preg_replace( '/[\(\)]/', '', $paramString );
  92.                     //we have the old style parms like {CODE (in=>1)}
  93.                     $params = explode( ',', trim( $paramString ) );
  94.  
  95.                     foreach( $params as $param ) {
  96.                         // the following str_replace line is to decode the &gt; char when html is turned off
  97.                         // perhaps the plugin syntax should be changed in 1.8 not to use any html special chars
  98.                         $parts = preg_split( '/=>?/', $param );
  99.  
  100.                         if( isset( $parts[0] ) && isset( $parts[1] ) ) {
  101.                             $name = trim( $parts[0] );
  102.                             $arguments[$name] = trim( $parts[1] );
  103.                         }
  104.                     }
  105.                 } else {
  106.                     $paramString = trim( $curlyTags[2][$i][0], " \t()" );
  107.                     $paramString = str_replace("&quot;", '"', $paramString);
  108.                     $arguments = parse_xml_attributes( $paramString );
  109.                 }
  110.  
  111.                 if( $ret = $loadFunc( $plugin_data, $arguments, $pCommonObject, $pParseHash )) {
  112.                     $key = "parseprotect".md5( mt_rand() );
  113.                     $pReplace[] = array(
  114.                         'key'  => $key,
  115.                         'data' => $ret,
  116.                     );
  117.  
  118.                     // don't modify data if $pos is FALSE
  119.                     if( $pos !== FALSE ) {
  120.                         $pData = substr_replace( $pData, $key, $pos, $pos_end - $pos + strlen( $plugin_end ));
  121.                     }
  122.                 }
  123.             }
  124.             $i--;
  125.             // if we are in CODE parsing mode and list is done, switch to 'parse other plugins' mode and start all over
  126.             if( ( $code_first ) && ( $i < 0 ) ) {
  127.                 $i = count( $curlyTags[0] ) - 1;
  128.                 $code_first = FALSE;
  129.             }
  130.         } // while
  131.     }
  132. }
  133.  
  134. /**
  135.  * This function replaces pre- and no-parsed sections with unique keys and
  136.  * saves the section contents for later reinsertion. It is needed by
  137.  * parse_data_plugins() to extract sections that don't require parsing
  138.  *
  139.  * @param array $pData data that might contain ~np~ or ~pp~ strings
  140.  * @param array $preparsed array that is updated by refrerence with key and data that needs to be substituted later
  141.  * @param array $noparsed array that is updated by refrerence with key and data that needs to be substituted later
  142.  * @access public
  143.  * @return void 
  144.  */
  145. function parse_protect( &$pData, &$pReplace ) {
  146.     // Find all sections delimited by ~pp~ ... ~/pp~
  147.     preg_match_all( "/\~pp\~(.*?)\~\/pp\~/s", $pData, $preparse );
  148.     if( count( $preparse[0] )) {
  149.         foreach( array_unique( $preparse[1] ) as $pp ) {
  150.             $aux["key"]  = md5( mt_rand() );
  151.             $aux["data"] = "<pre><code>".htmlspecialchars( $pp )."</code></pre>";
  152.             $pReplace[]  = $aux;
  153.             $pData       = str_replace( "~pp~$pp~/pp~", $aux['key'], $pData );
  154.         }
  155.     }
  156.  
  157.     // now remove <pre>...<pre> sections
  158.     preg_match_all( "!(<pre[^>]*>)(.*?)(</pre[^>]*>)!si", $pData, $preparse );
  159.     if( count( $preparse[0] )) {
  160.         foreach( $preparse[2] as $key => $pre ) {
  161.             $aux["key"]  = md5( mt_rand() );
  162.             $aux["data"] = $preparse[1][$key].htmlspecialchars( $pre ).$preparse[3][$key];
  163.             $pReplace[]  = $aux;
  164.             $pData       = str_replace( $preparse[1][$key].$pre.$preparse[3][$key], $aux['key'], $pData );
  165.         }
  166.     }
  167.  
  168.     // and now ~np~...~/np~ sections
  169.     preg_match_all( "/\~np\~(.*?)\~\/np\~/s", $pData, $noparse );
  170.     if( count( $noparse[0] )) {
  171.         foreach( array_unique( $noparse[1] ) as $np ) {
  172.             $aux["key"]  = md5( mt_rand() );
  173.             $aux["data"] = htmlspecialchars( $np );
  174.             $pReplace[]  = $aux;
  175.             $pData       = str_replace( "~np~$np~/np~", $aux['key'], $pData );
  176.         }
  177.     }
  178. }
  179.  
  180.  
  181. // ================== Liberty Plugin Helper ==================
  182. /**
  183.  * pass in the plugin paramaters and out comes a hash with usable styling information
  184.  *
  185.  * @param array $pParamHash 
  186.  * @access public
  187.  * @return hash full of styling goodies
  188.  */
  189. function liberty_plugins_wrapper_style( $pParamHash ) {
  190.     global $gBitSystem;
  191.  
  192.     $ret = array();
  193.     $ret['style'] = $ret['description'] = '';
  194.  
  195.     if( !empty( $pParamHash ) && is_array( $pParamHash )) {
  196.         // if align is right and text-align isn't set, we'll align that right as well
  197.         if( empty( $pParamHash['text-align'] ) && ( !empty( $pParamHash['align'] ) && $pParamHash['align'] == 'right' || !empty( $pParamHash['align'] ) && $pParamHash['align'] == 'right' )) {
  198.             $pParamHash['text-align'] = 'right';
  199.         }
  200.  
  201.         // this defines what the wrapper should be - div or span
  202.         // if someone sets this value manually, they know what they are doing
  203.         if( empty( $pParamHash['wrapper'] )) {
  204.             $pParamHash['wrapper'] = 'div';
  205.  
  206.             if( $gBitSystem->isFeatureActive( 'liberty_use_span_wrapper' )) {
  207.                 // set to 'span' if desired
  208.                 $pParamHash['wrapper'] = 'span';
  209.  
  210.                 // force display:block to the "div" if not specified otherwise
  211.                 if( empty( $pParamHash['display'] )) {
  212.                     $pParamHash['display'] = "inline-block";
  213.                 }
  214.             }
  215.         }
  216.  
  217.         foreach( $pParamHash as $key => $value ) {
  218.             if( !empty( $value )) {
  219.                 switch( $key ) {
  220.                     // description
  221.                     case 'desc':
  222.                         $key = 'description';
  223.                     case 'description':
  224.                         $ret[$key] = $value;
  225.                         break;
  226.                     // styling
  227.                     case 'width':
  228.                     case 'height':
  229.                         if( preg_match( "/^\d+(em|px|%|pt)$/", trim( $value ))) {
  230.                             $ret['style'] .= "{$key}:{$value};";
  231.                         } elseif( preg_match( "/^\d+$/", $value )) {
  232.                             $ret['style'] .= "{$key}:{$value}px;";
  233.                         }
  234.                         break;
  235.                     case 'background':
  236.                     case 'background-color':
  237.                     case 'border':
  238.                     case 'color':
  239.                     case 'display':
  240.                     case 'float':
  241.                     case 'font':
  242.                     case 'font-family':
  243.                     case 'font-size':
  244.                     case 'font-weight':
  245.                     case 'margin':
  246.                     case 'overflow':
  247.                     case 'padding':
  248.                     case 'text-align':
  249.                         $ret['style'] .= "{$key}:{$value};";
  250.                         break;
  251.                     // align and float are special
  252.                     case 'align':
  253.                         if( $value == 'center' || $value == 'middle' ) {
  254.                             $ret['style'] .= 'text-align:center;';
  255.                         } else {
  256.                             $ret['style'] .= "float:{$value};";
  257.                         }
  258.                         break;
  259.                     // default just gets re-assigned
  260.                     default:
  261.                         $ret[$key] = $value;
  262.                         break;
  263.                 }
  264.             }
  265.         }
  266.     }
  267.  
  268.     return $ret;
  269. }
  270.  
  271.  
  272. // ================== Liberty Service Functions ==================
  273. /**
  274.  * liberty_content_load_sql
  275.  *
  276.  * @access public
  277.  * @return content load sql
  278.  */
  279. function liberty_content_load_sql( &$pObject, $pParamHash=NULL ) {
  280.     global $gBitSystem, $gBitUser;
  281.     $ret = array();
  282.  
  283.     $hasPerm = ( is_object( $pObject ) && isset( $pObject->hasUserPermission )) ? $pObject->hasUserPermission( 'p_liberty_edit_all_status' ) : $gBitUser->hasPermission( 'p_liberty_edit_all_status' );
  284.  
  285.     if( $gBitSystem->isFeatureActive( 'liberty_display_status' ) && !$hasPerm ) {
  286.         if(( is_object( $pObject ) && !empty( $pObject->mType['content_type_guid'] ) && $pObject->mType['content_type_guid'] == 'bitcomment' )
  287.             || ( !empty( $pParamHash['include_comments'] ) && $pParamHash['include_comments']  == 'y' )) {
  288.             // if we are getting a list of comments then lets check the owner of the comment root and the owner of the content
  289.                 $ret['join_sql'] = "
  290.                     INNER JOIN `".BIT_DB_PREFIX."liberty_comments` lcoms ON (lc.`content_id` = lcoms.`content_id`)
  291.                     INNER JOIN `".BIT_DB_PREFIX."liberty_content` rlcs ON( rlcs.`content_id`=lcoms.`root_id` )";
  292.             $ret['where_sql'] = " AND lc.`content_status_id` < 100 AND ( ( (rlcs.`user_id` = '".$gBitUser->getUserId()."' OR lc.`user_id` = '".$gBitUser->getUserId()."') AND lc.`content_status_id` > -100) OR lc.`content_status_id` > 0 )";
  293.         } else {
  294.             // let owner see any of their own content with a status > -100
  295.             $ret['where_sql'] = " AND lc.`content_status_id` < 100 AND ( (lc.`user_id` = '".$gBitUser->getUserId()."' AND lc.`content_status_id` > -100) OR lc.`content_status_id` > 0 )";
  296.         }
  297.     }
  298.  
  299.     // Make sure owner comes out properly for all content
  300.     if ($gBitSystem->isFeatureActive('liberty_allow_change_owner') && $gBitUser->hasPermission('p_liberty_edit_content_owner')) {
  301.         $ret['select_sql'] = " , lc.`user_id` AS owner_id";
  302.     }
  303.     return $ret;
  304. }
  305.  
  306. /**
  307.  * liberty_content_list_sql
  308.  *
  309.  * @param array $pParamHash 
  310.  * @param array $pParamHash['enforce_status'] will add joins to status_id even if user is admin
  311.  * @param array $pParamHash['min_status_id'] one less than the minimum status a content can have to be included
  312.  * @param array $pParamHash['max_status_id'] one more than the maximum status a content can have to be included
  313.  * @param array $pParamHash['min_owner_status_id'] one less than the mimimum status a content can have to be included that is owned by the requester
  314.  * @access public
  315.  * @return content list sql
  316.  */
  317. function liberty_content_list_sql( &$pObject, $pParamHash=NULL ) {
  318.     global $gBitSystem, $gBitUser;
  319.     $ret = array();
  320.  
  321.     $hasPerm = FALSE;
  322.     // enforce_status will require the status limit on everyone including admin and thus we can ignore permission checks
  323.     if( !isset( $pParamHash['enforce_status'] )) {
  324.         $hasPerm = ( is_object( $pObject ) && method_exists( $pObject, 'hasUserPermission' )) ? $pObject->hasUserPermission( 'p_liberty_edit_all_status', FALSE ) : $gBitUser->hasPermission( 'p_liberty_edit_all_status' );
  325.     }
  326.  
  327.     // default show content with status between 0 and 100;
  328.     $min_status_id = isset( $pParamHash['min_status_id'] ) && ( @BitBase::verifyId( $pParamHash['min_status_id'] ) || $pParamHash['min_status_id'] === 0 ) ? $pParamHash['min_status_id'] : 0;
  329.     $max_status_id = isset( $pParamHash['max_status_id'] ) && ( @BitBase::verifyId( $pParamHash['max_status_id'] ) || $pParamHash['max_status_id'] === 0 ) ? $pParamHash['max_status_id'] : 100;
  330.     // let owner see any of their own content with a status > -100
  331.     $min_owner_status_id = isset( $pParamHash['min_owner_status_id'] ) && ( @BitBase::verifyId( $pParamHash['min_owner_status_id'] ) || $pParamHash['min_owner_status_id'] === 0 ) ? $pParamHash['min_owner_status_id'] : -100;
  332.  
  333.     if( $gBitSystem->isFeatureActive('liberty_display_status') && !$hasPerm ) {
  334.         if(( is_object( $pObject ) && !empty( $pObject->mType['content_type_guid'] ) && $pObject->mType['content_type_guid'] == 'bitcomment' )
  335.             || ( !empty( $pParamHash['include_comments'] ) && $pParamHash['include_comments']  == 'y' )) {
  336.             // if we are getting a list of comments then lets check the owner of the comment root and the owner of the content
  337.             $ret['join_sql'] = "
  338.                     LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_comments` lcoms ON (lc.`content_id` = lcoms.`content_id`)
  339.                     LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_content` rlcs ON( rlcs.`content_id`=lcoms.`root_id` )";
  340.             $ret['where_sql'] =
  341.                 " AND lc.`content_status_id` < ".$max_status_id.
  342.                 " AND (
  343.                     ( (rlcs.`user_id` = '".$gBitUser->getUserId()."' OR lc.`user_id` = '".$gBitUser->getUserId()."') AND lc.`content_status_id` > ".$min_owner_status_id.")
  344.                     OR lc.`content_status_id` > ".$min_status_id."
  345.                 )";
  346.         } else {
  347.             $ret['where_sql'] =
  348.                 " AND lc.`content_status_id` < ".$max_status_id.
  349.                 " AND (
  350.                     (lc.`user_id` = '".$gBitUser->getUserId()."' AND lc.`content_status_id` > ".$min_owner_status_id.")
  351.                     OR lc.`content_status_id` > ".$min_status_id."
  352.                 )";
  353.         }
  354.     }
  355.  
  356.     return $ret;
  357. }
  358.  
  359. /**
  360.  * liberty_content_preview
  361.  *
  362.  * @param array $pObject 
  363.  * @access public
  364.  * @return void 
  365.  */
  366. function liberty_content_preview( &$pObject ) {
  367.     global $gBitSystem, $gBitUser;
  368.     if( $gBitSystem->isFeatureActive( 'liberty_display_status' )
  369.         && ( $gBitUser->hasPermission( 'p_liberty_edit_content_status' ) || $gBitUser->hasPermission( 'p_libert_edit_all_status' ))
  370.         && @BitBase::verifyId( $_REQUEST['content_status_id'] )) {
  371.         $pObject->mInfo['content_status_id'] = $_REQUEST['content_status_id'];
  372.     }
  373.     if( $gBitSystem->isFeatureActive( 'liberty_allow_change_owner' )
  374.         && $gBitUser->hasPermission( 'p_liberty_edit_content_owner' )
  375.         && @BitBase::verifyId( $_REQUEST['owner_id'] )) {
  376.         $pObject->mInfo['owner_id'] = $_REQUEST['owner_id'];
  377.     }
  378.     include_once( LIBERTY_PKG_PATH.'edit_help_inc.php' );
  379. }
  380.  
  381. /**
  382.  * liberty_content_display
  383.  *
  384.  * @param array $pObject 
  385.  * @param array $pParamHash 
  386.  * @access public
  387.  * @return void 
  388.  */
  389. function liberty_content_display( &$pObject, &$pParamHash ) {
  390.     if( $pObject->isValid() ) {
  391.         global $gBitUser, $gBitSystem;
  392.  
  393.         // make sure user has appropriate permissions to view this content
  394.         if( !empty( $pParamHash['perm_name'] )) {
  395.             $pObject->verifyViewPermission();
  396.         }
  397.     }
  398. }
  399.  
  400. /**
  401.  * liberty_content_edit
  402.  *
  403.  * @param array $pObject 
  404.  * @param array $pParamHash 
  405.  * @access public
  406.  * @return void 
  407.  */
  408. function liberty_content_edit( &$pObject ) {
  409.     include_once( LIBERTY_PKG_PATH.'edit_help_inc.php' );
  410.     include_once( LIBERTY_PKG_PATH."edit_storage_inc.php" );
  411. }
  412.  
  413.  
  414. // ================== Liberty File Processing Functions ==================
  415.  
  416. /**
  417.  * Process uploaded files. Will automagically generate thumbnails for images
  418.  *
  419.  * @param array $pFileHash Data require to process the files
  420.  * @param array $pFileHash['name'] (required) Name of the uploaded file
  421.  * @param array $pFileHash['type'] (required) Mime type of the file uploaded
  422.  * @param array $pFileHash['dest_branch'] (required) Relative path where you want to store the file (trailing slash required)
  423.  * @param array $pFileHash['tmp_name'] (required) Absolute path to file including file name
  424.  * @param boolean $pFileHash['thumbnail'] (optional) Set to FALSE if you don't want to generate thumbnails
  425.  * @param array $pFileHash['thumbnail_sizes'] (optional) Decide what sizes thumbnails you want to create: icon, avatar, small, medium, large
  426.  * @param boolean $pMoveFile (optional) specify if you want to move or copy the original file
  427.  * @access public
  428.  * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  429.  */
  430. function liberty_process_upload( &$pFileHash, $pMoveFile = TRUE ) {
  431.     global $gBitSystem;
  432.  
  433.     // Check for evil file extensions that could be execed on the server
  434.     if( preg_match( EVIL_EXTENSION_PATTERN, $pFileHash['name'] )) {
  435.         $pFileHash['type'] = 'text/plain';
  436.         $pFileHash['name'] = $pFileHash['name'].'.txt';
  437.     }
  438.  
  439.     if ( !is_windows() ) {
  440.         list( $pFileHash['name'], $pFileHash['type'] ) = $gBitSystem->verifyFileExtension( $pFileHash['tmp_name'], $pFileHash['name'] );
  441.     } else {
  442.         //$pFile['type'] = $gBitSystem->verifyMimeType( $pFile['tmp_name'] );
  443.     }
  444.  
  445.     $ext = strrpos( $pFileHash['name'], '.' );
  446.  
  447.     // clean out crap that can make life difficult in server maintenance
  448.     $cleanedBaseName = preg_replace( '/[&\%:\/\\\]/', '', substr( $pFileHash['name'], 0, $ext ) );
  449.     $pFileHash['dest_base_name'] = $cleanedBaseName;
  450.     $pFileHash['source_file'] = $pFileHash['tmp_name'];
  451.     // lowercase all file extensions
  452.  
  453.     $pFileHash['name'] = $cleanedBaseName.strtolower( substr( $pFileHash['name'], $ext ) );
  454.  
  455.     // Thumbs.db is a windows My Photos/ folder file, and seems to really piss off imagick
  456.     $canThumbFunc = liberty_get_function( 'can_thumbnail' );
  457.     if( !empty( $canThumbFunc ) && $canThumbFunc( $pFileHash['type'] ) && $pFileHash['name'] != 'Thumbs.db' ) {
  458.         $ret = liberty_process_image( $pFileHash, $pMoveFile );
  459.     } else {
  460.         $ret = liberty_process_generic( $pFileHash, $pMoveFile );
  461.     }
  462.  
  463.     return $ret;
  464. }
  465.  
  466. /**
  467.  * liberty_process_archive
  468.  *
  469.  * @param array $pFileHash 
  470.  * @access public
  471.  * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  472.  */
  473. function liberty_process_archive( &$pFileHash ) {
  474.     // sanity check: make sure tmp_name isn't empty. will scan / if it is
  475.     if( !is_array( $pFileHash ) || empty( $pFileHash['tmp_name'] ) || empty( $pFileHash['name'] ) ) {
  476.         return FALSE;
  477.     }
  478.  
  479.     $cwd = getcwd();
  480.     // if the file has been uploaded using a form, we'll process the uploaded
  481.     // file directly. if it's been ftp uploaded or some other method used,
  482.     // we'll copy the file. in the case of xuploaded files, the files have been
  483.     // processed but don't have to be copied
  484.     if( empty( $pFileHash['preprocessed'] ) && !is_uploaded_file( $pFileHash['tmp_name'] ) && is_file( $pFileHash['tmp_name'] ) ) {
  485.         $tmpDir = get_temp_dir();
  486.         $copyFile = tempnam( !empty( $tmpDir ) ? $tmpDir : '/tmp', $pFileHash['name'] );
  487.         copy( $pFileHash['tmp_name'], $copyFile );
  488.         $pFileHash['tmp_name'] = $copyFile;
  489.     }
  490.  
  491.     $dir = dirname( $pFileHash['tmp_name'] );
  492.     $upExt = strtolower( substr( $pFileHash['name'], ( strrpos( $pFileHash['name'], '.' ) + 1 ) ) );
  493.     $baseDir = $dir.'/';
  494.     if( is_file( $pFileHash['tmp_name'] ) ) {
  495.         global $gBitUser;
  496.         $baseDir .= $gBitUser->mUserId;
  497.     }
  498.  
  499.     $destDir = $baseDir.'/'.basename( $pFileHash['tmp_name'] );
  500.     // this if is very important logic back so subdirs get processed properly
  501.     if( ( is_dir( $baseDir ) || mkdir( $baseDir ) ) && @mkdir( $destDir ) ) {
  502.         // Some commands don't nicely support extracting to other directories
  503.         chdir( $destDir );
  504.         list( $mimeType, $mimeExt ) = explode( '/', strtolower( $pFileHash['type'] ) );
  505.         switch( $mimeExt ) {
  506.             case 'x-rar-compressed':
  507.             case 'x-rar':
  508.                 $shellResult = shell_exec( "unrar x \"{$pFileHash['tmp_name']}\" \"$destDir\"" );
  509.                 break;
  510.             case 'x-bzip2':
  511.             case 'bzip2':
  512.             case 'x-gzip':
  513.             case 'gzip':
  514.             case 'x-tgz':
  515.             case 'x-tar':
  516.             case 'tar':
  517.                 switch( $upExt ) {
  518.                     case 'gz':
  519.                     case 'tgz': $compressFlag = '-z'; break;
  520.                     case 'bz2': $compressFlag = '-j'; break;
  521.                     default: $compressFlag = ''; break;
  522.                 }
  523.                 $shellResult = shell_exec( "tar -x $compressFlag -f \"{$pFileHash['tmp_name']}\"  -C \"$destDir\"" );
  524.                 break;
  525.             case 'x-zip-compressed':
  526.             case 'x-zip':
  527.             case 'zip':
  528.                 $shellResult = shell_exec( "unzip \"{$pFileHash['tmp_name']}\" -d \"$destDir\"" );
  529.                 break;
  530.             case 'x-stuffit':
  531.             case 'stuffit':
  532.                 $shellResult = shell_exec( "unstuff -d=\"$destDir\" \"{$pFileHash['tmp_name']}\" " );
  533.                 break;
  534.             default:
  535.                 if( $upExt == 'zip' ) {
  536.                     $shellResult = shell_exec( "unzip \"{$pFileHash['tmp_name']}\" -d \"$destDir\"" );
  537.                 } elseif( $upExt == 'rar' ) {
  538.                     $shellResult = shell_exec( "unrar x \"{$pFileHash['tmp_name']}\" \"$destDir\"" );
  539.                 } elseif( $upExt == 'sit' || $upExt == 'sitx' ) {
  540.                     print( "unstuff -d=\"$destDir\" \"{$pFileHash['tmp_name']}\" " );
  541.                     $shellResult = shell_exec( "unstuff -d=\"$destDir\" \"{$pFileHash['tmp_name']}\" " );
  542.                 } else {
  543.                     $destDir = NULL;
  544.                 }
  545.                 break;
  546.         }
  547.     }
  548.  
  549.     chdir( $cwd );
  550.  
  551.     // if we created a copy of the original, we remove it
  552.     if( !empty( $copyFile ) ) {
  553.         @unlink( $copyFile );
  554.     }
  555.  
  556.     if( preg_match( "!^/+$!", $destDir )) {
  557.         // obviously something went horribly wrong
  558.         return FALSE;
  559.     } else {
  560.         return $destDir;
  561.     }
  562. }
  563.  
  564. /**
  565.  * liberty_process_generic
  566.  *
  567.  * @param array $pFileHash 
  568.  * @param array $pMoveFile 
  569.  * @access public
  570.  * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  571.  */
  572. function liberty_process_generic( &$pFileHash, $pMoveFile = TRUE ) {
  573.     global $gBitSystem;
  574.     $ret = NULL;
  575.     if( !empty( $pFileHash['dest_file'] ) ) {
  576.         $destFile = $pFileHash['dest_file'];
  577.     } else {
  578.         if( $gBitSystem->isFeatureActive( 'liberty_originalize_file_names' ) ) {
  579.             $destFile = STORAGE_PKG_PATH.$pFileHash['dest_branch'].liberty_mime_get_default_file_name( $pFileHash['name'], $pFileHash['type'] );
  580.         } else {
  581.             $destFile = STORAGE_PKG_PATH.$pFileHash['dest_branch'].$pFileHash['name'];
  582.         }
  583.         if ( is_windows() ) {
  584.             $destFile = str_replace( '//', '\\', str_replace( "\\", '\\', $destFile ) );
  585.         }
  586.     }
  587.  
  588.     mkdir_p( dirname( $destFile ) );
  589.  
  590.     if( is_file( $pFileHash['source_file']) ) {
  591.         if( $pFileHash['source_file'] == $destFile ) {
  592.             // do nothing if source and dest are the same
  593.         } elseif( $pMoveFile ) {
  594.             if( is_uploaded_file( $pFileHash['source_file'] ) ) {
  595.                 move_uploaded_file( $pFileHash['source_file'], $destFile );
  596.             } else {
  597.                 rename( $pFileHash['source_file'], $destFile );
  598.             }
  599.         } else {
  600.             copy( $pFileHash['source_file'], $destFile );
  601.         }
  602.         $ret = $destFile;
  603.     }
  604.     $pFileHash['size'] = filesize( $destFile );
  605.  
  606.     return $ret;
  607. }
  608.  
  609.  
  610. /**
  611.  * liberty_process_image
  612.  *
  613.  * @param array $pFileHash 
  614.  * @access public
  615.  * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  616.  */
  617. function liberty_process_image( &$pFileHash, $pMoveFile = TRUE ) {
  618.     global $gBitSystem;
  619.     $ret = NULL;
  620.  
  621.     list($type, $ext) = explode( '/', strtolower( $pFileHash['type'] ) );
  622.     if( $resizePath = liberty_process_generic( $pFileHash, $pMoveFile )) {
  623.         $pFileHash['source_file'] = $resizePath;
  624.  
  625.         //set permissions if possible - necessary for some wonky shared hosting environments
  626.         if(chmod($pFileHash['source_file'], 0644)){
  627.             //does nothing, but fails elegantly
  628.         }
  629.         $nameHold = $pFileHash['name'];
  630.         $sizeHold = $pFileHash['size'];
  631.         $ret = $pFileHash['source_file'];
  632.  
  633.         // do not thumbnail only if intentionally set to FALSE
  634.         if( !isset( $pFileHash['thumbnail'] ) || $pFileHash['thumbnail']==TRUE ) {
  635.             liberty_generate_thumbnails( $pFileHash );
  636.         }
  637.         $pFileHash['name'] = $nameHold;
  638.         $pFileHash['size'] = $sizeHold;
  639.     }
  640.     return $ret;
  641. }
  642.  
  643. /**
  644.  * liberty_clear_thumbnails will clear all thummbnails found in a given directory
  645.  *
  646.  * @param array $pFileHash['dest_branch'] should contain the path to the dir where we should remove thumbnails
  647.  * @access public
  648.  * @return TRUE on success, FALSE on failure
  649.  */
  650. function liberty_clear_thumbnails( &$pFileHash ) {
  651.     if( !empty( $pFileHash['dest_branch'] )) {
  652.         $thumbHash = array(
  653.             'source_file' => $pFileHash['dest_branch'],
  654.             'mime_image'   => FALSE,
  655.         );
  656.  
  657.         // get thumbnails we want to remove
  658.         if( $thumbs = liberty_fetch_thumbnails( $thumbHash )) {
  659.             foreach( $thumbs as $thumb ) {
  660.                 $thumb = BIT_ROOT_PATH.$thumb;
  661.                 if( is_writable( $thumb )) {
  662.                     unlink( $thumb );
  663.                 }
  664.             }
  665.             // if this was the thumbs subdirectory, we'll remove it if it's empty
  666.             if( basename( dirname( $thumb )) == 'thumbs' ) {
  667.                 @rmdir( dirname( $thumb ));
  668.             }
  669.         }
  670.     }
  671.     return TRUE;
  672. }
  673.  
  674. /**
  675.  * liberty_get_function
  676.  *
  677.  * @param array $pType 
  678.  * @access public
  679.  * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  680.  */
  681. function liberty_get_function( $pType ) {
  682.     global $gBitSystem;
  683.     $ret = 'liberty_'.$gBitSystem->getConfig( 'image_processor', 'gd' ).'_'.$pType.'_image';
  684.     return( function_exists( $ret ) ? $ret : FALSE );
  685. }
  686.  
  687. /**
  688.  * liberty_generate_thumbnails
  689.  *
  690.  * @param array $pFileHash 
  691.  * @access public
  692.  * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  693.  */
  694. function liberty_generate_thumbnails( $pFileHash ) {
  695.     global $gBitSystem, $gThumbSizes;
  696.     $resizeFunc = liberty_get_function( 'resize' );
  697.     $ret = FALSE;
  698.  
  699.     // allow custom selection of thumbnail sizes
  700.     if( empty( $pFileHash['thumbnail_sizes'] )) {
  701.         if( !empty( $gThumbSizes ) && is_array( $gThumbSizes )) {
  702.             $pFileHash['thumbnail_sizes'] = array_keys( $gThumbSizes );
  703.         } else {
  704.             $pFileHash['thumbnail_sizes'] = array( 'large', 'medium', 'small', 'avatar', 'icon' );
  705.         }
  706.     }
  707.  
  708.     if( ( !preg_match( '#image/(gif|jpe?g|png)#i', $pFileHash['type'] ) && $gBitSystem->isFeatureActive( 'liberty_jpeg_originals' )) || in_array( 'original', $pFileHash['thumbnail_sizes'] ) ) {
  709.         // jpeg version of original
  710.         if( preg_match( '/pdf/i', $pFileHash['type'] ) ) {
  711.             // has a customer pdf rasterization function been defined?
  712.             if( function_exists( 'liberty_rasterize_pdf' ) && $rasteredFile = liberty_rasterize_pdf( $pFileHash['source_file'] ) ) {
  713.                 $pFileHash['source_file'] = $rasteredFile;
  714.             } else {
  715.                 MagickSetImageUnits( $magickWand, MW_PixelsPerInchResolution );
  716.                 $rez =  empty( $pFileHash['max_width'] ) || $pFileHash['max_width'] == MAX_THUMBNAIL_DIMENSION ? 250 : 72;
  717.                 MagickSetResolution( $magickWand, 300, 300 );
  718.             }
  719.         } else {
  720.             $pFileHash['dest_base_name'] = 'original';
  721.             $pFileHash['name'] = 'original.jpg';
  722.             $pFileHash['max_width'] = MAX_THUMBNAIL_DIMENSION;
  723.             $pFileHash['max_height'] = MAX_THUMBNAIL_DIMENSION;
  724.             if( $convertedFile = $resizeFunc( $pFileHash )) {
  725.                 $pFileHash['source_file'] = $convertedFile;
  726.                 $ret = TRUE;
  727.             }
  728.         }
  729.         $pFileHash['type'] = $gBitSystem->verifyMimeType( $pFileHash['source_file'] );
  730.     }
  731.  
  732.     // override $mimeExt if we have a custom setting for it
  733.     if( $gBitSystem->isFeatureActive( 'liberty_thumbnail_format' )) {
  734.         $mimeExt = $gBitSystem->getConfig( 'liberty_thumbnail_format' );
  735.     } else {
  736.         list( $type, $mimeExt ) = preg_split( '#/#', strtolower( $pFileHash['type'] ));
  737.     }
  738.  
  739.     if( preg_match( "!(png|gif)!", $mimeExt )) {
  740.         $destExt = '.'.$mimeExt;
  741.     } else {
  742.         $destExt = '.jpg';
  743.     }
  744.  
  745.     $initialDestPath = $pFileHash['dest_branch'];
  746.     foreach( $pFileHash['thumbnail_sizes'] as $thumbSize ) {
  747.         if( isset( $gThumbSizes[$thumbSize] )) {
  748.             $pFileHash['dest_base_name'] = $thumbSize;
  749.             $pFileHash['name'] = $thumbSize.$destExt;
  750.             if( !empty( $gThumbSizes[$thumbSize]['width'] )) {
  751.                 $pFileHash['max_width'] = $gThumbSizes[$thumbSize]['width'];
  752.             } else {
  753.                 // Have to unset since we reuse $pFileHash
  754.                 unset( $pFileHash['max_width'] );
  755.             }
  756.  
  757.             // reset dest_branch for created thumbs
  758.             if( !empty( $pFileHash['thumb_path'] ) ) {
  759.                 $pFileHash['dest_file'] = $pFileHash['thumb_path'].$pFileHash['name'];
  760.             } else {
  761.                 // create a subdirectory for the thumbs
  762.                 $pFileHash['dest_branch'] = $initialDestPath.'thumbs/';
  763.                 clearstatcache();
  764.                 if( !is_dir( STORAGE_PKG_PATH.$pFileHash['dest_branch'] )) {
  765.                     mkdir( STORAGE_PKG_PATH.$pFileHash['dest_branch'], 0775, TRUE );
  766.                     clearstatcache();
  767.                 }
  768.             }
  769.  
  770.             if( !empty( $gThumbSizes[$thumbSize]['height'] )) {
  771.                 $pFileHash['max_height'] = $gThumbSizes[$thumbSize]['height'];
  772.             } else {
  773.                 // Have to unset since we reuse $pFileHash
  774.                 unset( $pFileHash['max_height'] );
  775.             }
  776.  
  777.             if( $pFileHash['icon_thumb_path'] = $resizeFunc( $pFileHash )) {
  778.                 $ret = TRUE;
  779.                 // use the previous thumb as the source for the next, decreasingly smaller thumb as this GREATLY increases speed
  780.                 $pFileHash['source_file'] = $pFileHash['icon_thumb_path'];
  781.             }
  782.         }
  783.     }
  784.  
  785.     // to keep everything in bitweaver working smoothly, we need to remove the thumbs/ subdir again
  786.     $pFileHash['dest_branch'] = $initialDestPath;
  787.  
  788.     return $ret;
  789. }
  790.  
  791. /**
  792.  * fetch all available thumbnails for a given item. if no thumbnails are present, get thumbnailing image or the appropriate mime type icon
  793.  *
  794.  * @param array   $pParamHash Hash of all settings used to fetch thumbnails, including source_file, default_image, thumbnail_sizes, and mime_image
  795.  * @access public
  796.  * @return array of available thumbnails or mime icons
  797.  *  TODO: individual options are only for legacy reasons - remove options and deprecated() soon - xing - Monday Jun 23, 2008   22:36:53 CEST
  798.  */
  799. function liberty_fetch_thumbnails( $pParamHash ) {
  800.     global $gBitSystem, $gThumbSizes;
  801.     $ret = array();
  802.  
  803.     if( !empty( $pParamHash['source_file'] )) {
  804.         if( empty( $pParamHash['thumbnail_sizes'] )) {
  805.             $pParamHash['thumbnail_sizes'] = array_keys( $gThumbSizes );
  806.         }
  807.  
  808.         // liberty file processors automatically pick the best format for us. we can force a format though.
  809.         // using array_unique will give us the best order in which to look for the thumbnails
  810.         $exts = array_unique( array( $gBitSystem->getConfig( 'liberty_thumbnail_format', 'jpg' ), 'jpg', 'png', 'gif', 'x-jpeg' ));
  811.  
  812.         // short hand
  813.         $path = &$pParamHash['source_file'];
  814.         // $path might already be the absolute path or it might already contain BIT_ROOT_URL
  815.         if( !( $path = preg_replace( "!^".preg_quote( STORAGE_PKG_PATH, "!" )."!", "", $path ))) {
  816.             $path = preg_replace( "!^".preg_quote( STORAGE_PKG_URL, "!" )."!", "", $path );
  817.         }
  818.  
  819.         // remove the filename if there is one (we can't just use dirname() becuase we might only have the path to the dir)
  820.         $dir = substr( $path, 0, strrpos( $path, '/' ) + 1 );
  821.         // assume thumb sizes are from largest to smallest. reverse so smaller can be used if larger don't exist
  822.         $lastSize = NULL;
  823.         foreach( array_reverse( $pParamHash['thumbnail_sizes'] ) as $size ) {
  824.             foreach( $exts as $ext ) {
  825.                 $image = $size.'.'.$ext;
  826.                 $thumbDir = is_dir( STORAGE_PKG_PATH.$dir.'thumbs/' ) ?  $dir.'thumbs/' :  $dir;
  827.                 if( is_readable( STORAGE_PKG_PATH.$thumbDir.$image )) {
  828.                     $ret[$size] = (empty( $_REQUEST['uri_mode'] ) ? STORAGE_PKG_URL : STORAGE_PKG_URI).$thumbDir.$image;
  829.                 }
  830.             }
  831.             // fetch mime image unless we set this to FALSE
  832.             if(( !isset( $pParamHash['mime_image'] ) || $pParamHash['mime_image'] === TRUE ) && empty( $ret[$size] )) {
  833.                 if( $lastSize && !empty( $ret[$lastSize] ) ) {
  834.                     $ret[$size] = $ret[$lastSize];
  835.                 }
  836.             }
  837.             $lastSize = $size;
  838.         }
  839.  
  840.         // default if nothing else is available
  841.         foreach( array_reverse( $pParamHash['thumbnail_sizes'] ) as $size ) {
  842.             if( empty( $ret[$size] ) ) {
  843.                 if( !empty( $pParamHash['default_image'] )) {
  844.                     $ret[$size] = $pParamHash['default_image'];
  845.                 } else {
  846.                     // we need to make sure we have an image name that we can look up the mime type
  847.                     $path .= ( strrpos( $dir, '/' ) == strlen( $path ) ? 'dummy.jpg' : basename( $path ));
  848.                     $ret[$size] = LibertySystem::getMimeThumbnailURL( $gBitSystem->lookupMimeType( $path ), substr( $path, strrpos( $path, '.' ) + 1 ));
  849.                 }
  850.             }
  851.         }
  852.     }
  853.  
  854.     return $ret;
  855. }
  856.  
  857. /**
  858.  * fetch a single available thumbnail for a given item. if no thumbnail is present, return NULL
  859.  *
  860.  * @param array   $pParamHash Hash of all settings used to fetch thumbnails including: size, source_file, default_image, and mime_image
  861.  * @access public
  862.  * @return string url
  863.  *  TODO: individual options are only for legacy reasons - remove options and deprecated() soon - xing - Monday Jun 23, 2008   22:36:53 CEST
  864.  */
  865. function liberty_fetch_thumbnail_url( $pParamHash ) {
  866.     if( !empty( $pParamHash['source_file'] )) {
  867.         if( empty( $pParamHash['size'] )) {
  868.             $pParamHash['size'] = 'small';
  869.         }
  870.  
  871.         $pParamHash['thumbnail_sizes'] = array( $pParamHash['size'] );
  872.         $ret = liberty_fetch_thumbnails( $pParamHash );
  873.  
  874.         return( !empty( $ret[$pParamHash['size']] ) ? $ret[$pParamHash['size']] : NULL );
  875.     }
  876. }
  877.  
  878. /**
  879.  * get a set of image size options based on $gThumbSizes
  880.  *
  881.  * @param string $pEmptyOption string to use as empty option - if set to FALSE no empty string is eincluded - Note that string is tra()'d
  882.  * @access public
  883.  * @return array of image size options suitable for use in a form
  884.  */
  885. function get_image_size_options( $pEmptyOption = 'Disable this feature' ) {
  886.     global $gThumbSizes;
  887.     $ret = array();
  888.     if( !empty( $pEmptyOption )) {
  889.         $ret[''] = tra( $pEmptyOption );
  890.     }
  891.     foreach( $gThumbSizes as $key => $size ) {
  892.         $ret[$key] = tra( ucfirst( $key ))." ( ". ( empty( $size['width'] ) ? tra( 'unlimited' ) : $size['width'] ) ." x ". ( empty($size['height'] ) ? tra('unlimited') : $size['height'] ) ." ".tra( 'pixels' )." )";
  893.     }
  894.     return $ret;
  895. }
  896.  
  897. /**
  898.  * get_leadtitle will fetch the string before the liberty_subtitle_delimiter
  899.  *
  900.  * @param string $pString string that should be checked for the delimiter
  901.  * @access public
  902.  * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  903.  */
  904. function get_leadtitle( $pString ) {
  905.     global $gBitSystem;
  906.     return( substr( $pString, 0, strpos( $pString, $gBitSystem->getConfig( 'liberty_subtitle_delimiter', ':' ))));
  907. }
  908.  
  909. /**
  910.  * get_subtitle will fetch the string after the liberty_subtitle_delimiter
  911.  *
  912.  * @param string $pString string that should be checked for the delimiter
  913.  * @access public
  914.  * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  915.  */
  916. function get_subtitle( $pString ) {
  917.     global $gBitSystem;
  918.     if(( $start = strpos( $pString, $gBitSystem->getConfig( 'liberty_subtitle_delimiter', ':' ))) !== FALSE ) {
  919.         return( substr( $pString, ( $start + 1 )));
  920.     }
  921. }
  922. ?>

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