2016-01-30 20:28:43 +00:00
< ? php
/*--------------------------------------------------------------------------------------------------------| www . vdm . io |------/
__ __ _ _____ _ _ __ __ _ _ _
\ \ / / | | | __ \ | | | | | \ / | | | | | | |
\ \ / / _ _ ___ | | _ | | | | _____ _____ | | ___ _ __ _ __ ___ ___ _ __ | | _ | \ / | ___ | | _ | | __ ___ __ | |
\ \ / / _ ` / __| __| | | | |/ _ \ \ / / _ \ |/ _ \| '_ \| '_ ` _ \ / _ \ '_ \| __| | |\/| |/ _ \ __| ' _ \ / _ \ / _ ` |
\ / ( _ | \__ \ | _ | | __ | | __ / \ V / __ / | ( _ ) | | _ ) | | | | | | __ / | | | | _ | | | | __ / | _ | | | | ( _ ) | ( _ | |
\ / \__ , _ | ___ / \__ | | _____ / \___ | \_ / \___ | _ | \___ /| . __ /| _ | | _ | | _ | \___ | _ | | _ | \__ | | _ | | _ | \___ | \__ | _ | | _ | \___ / \__ , _ |
| |
| _ |
/-------------------------------------------------------------------------------------------------------------------------------/
2017-02-09 16:11:10 +00:00
@ version 2.3 . 0
2016-01-30 20:28:43 +00:00
@ created 30 th April , 2015
@ package Component Builder
@ subpackage compiler . php
@ author Llewellyn van der Merwe < http :// www . vdm . io >
@ my wife Roline van der Merwe < http :// www . vdm . io />
@ copyright Copyright ( C ) 2015. All Rights Reserved
@ license GNU / GPL Version 2 or later - http :// www . gnu . org / licenses / gpl - 2.0 . html
Builds Complex Joomla Components
/-----------------------------------------------------------------------------------------------------------------------------*/
// No direct access to this file
defined ( '_JEXEC' ) or die ( 'Restricted access' );
2016-02-29 11:05:37 +00:00
// Use the component builder autoloader
2016-02-26 00:20:09 +00:00
ComponentbuilderHelper :: autoLoader ();
2016-01-30 20:28:43 +00:00
/**
* Compiler class
*/
2016-02-26 00:20:09 +00:00
class Compiler extends Infusion
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
/*
* The Temp path
*
* @ var string
*/
private $tempPath ;
public $filepath = '' ;
2016-01-30 20:28:43 +00:00
// fixed pathes
2016-11-22 05:48:55 +00:00
protected $dynamicIntegration = false ;
2016-02-26 00:20:09 +00:00
protected $backupPath = false ;
protected $gitPath = false ;
2017-02-09 16:11:10 +00:00
protected $addCustomCodeAt = array ();
2016-01-30 20:28:43 +00:00
/**
* Constructor
*/
public function __construct ( $config = array ())
{
2016-02-26 00:20:09 +00:00
// first we run the perent constructor
if ( parent :: __construct ( $config ))
2016-01-30 20:28:43 +00:00
{
// set temp directory
$comConfig = JFactory :: getConfig ();
$this -> tempPath = $comConfig -> get ( 'tmp_path' );
// set some folder paths in relation to distribution
if ( $config [ 'addBackup' ])
{
2016-11-22 05:48:55 +00:00
$this -> backupPath = $this -> params -> get ( 'backup_folder_path' , $this -> tempPath ) . '/' . $this -> componentBackupName . '.zip' ;
$this -> dynamicIntegration = true ;
2016-01-30 20:28:43 +00:00
}
if ( $config [ 'addGit' ])
{
$this -> gitPath = $this -> params -> get ( 'git_folder_path' , null );
}
2017-02-01 13:17:04 +00:00
// remove site folder if not needed (TODO add check if custom script was moved to site folder then we must do a more complex cleanup here)
2017-01-20 00:16:50 +00:00
if ( $this -> removeSiteFolder )
{
// first remove the files and folders
$this -> removeFolder ( $this -> componentPath . '/site' );
// clear form component xml
$xmlPath = $this -> componentPath . '/' . $this -> fileContentStatic [ '###component###' ] . '.xml' ;
$componentXML = JFile :: read ( $xmlPath );
$textToSite = ComponentbuilderHelper :: getBetween ( $componentXML , '<files folder="site">' , '</files>' );
$textToSiteLang = ComponentbuilderHelper :: getBetween ( $componentXML , '<languages folder="site">' , '</languages>' );
$componentXML = str_replace ( array ( '<files folder="site">' . $textToSite . " </files> " , '<languages folder="site">' . $textToSiteLang . " </languages> " ), array ( '' , '' ), $componentXML );
$this -> writeFile ( $xmlPath , $componentXML );
}
2016-02-26 00:20:09 +00:00
// now update the files
2017-02-01 13:17:04 +00:00
if ( ! $this -> updateFiles ())
2016-01-30 20:28:43 +00:00
{
2017-02-01 13:17:04 +00:00
return false ;
}
// we can remove all undeeded data
$this -> freeMemory ();
// check if this component is install on the current website
if ( $paths = $this -> getLocalInstallPaths ())
{
// start Automatic import of custom code
$userId = JFactory :: getUser () -> id ;
$today = JFactory :: getDate () -> toSql ();
// Get a db connection.
$db = JFactory :: getDbo ();
// get the custom code from installed files
$this -> customCodeFactory ( $paths , $db , $userId , $today );
}
// check if we have custom code to add
$this -> getCustomCode ();
2017-02-09 16:11:10 +00:00
// now add the other custom code by placeholder
if ( ComponentbuilderHelper :: checkArray ( $this -> addCustomCodeAt ))
{
// load error messages incase code can not be added
$app = JFactory :: getApplication ();
$this -> addCustomCodeViaPlaceholders ( $app );
}
2017-02-01 13:17:04 +00:00
// now insert into the new files
if ( ComponentbuilderHelper :: checkArray ( $this -> customCode ))
{
2017-02-04 00:22:17 +00:00
// load error messages incase code can not be added
$app = JFactory :: getApplication ();
$this -> addCustomCode ( $app );
2017-02-01 13:17:04 +00:00
}
// move the update server into place
$this -> setUpdateServer ();
// zip the component
if ( ! $this -> zipComponent ())
{
// done
return false ;
2016-01-30 20:28:43 +00:00
}
2017-02-01 13:17:04 +00:00
return true ;
2016-01-30 20:28:43 +00:00
}
return false ;
}
2016-09-03 21:44:47 +00:00
/**
* Set the line number in comments
*
* @ param int $nr The line number
*
* @ return void
*
*/
private function setLine ( $nr )
{
if ( $this -> loadLineNr )
{
return ' [Compiler ' . $nr . ']' ;
}
return '' ;
}
2017-02-01 13:17:04 +00:00
/**
* Set the dynamic data to the created fils
*
* @ return bool true on success
*
*/
2016-02-26 00:20:09 +00:00
protected function updateFiles ()
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
if ( isset ( $this -> newFiles [ 'static' ]) && ComponentbuilderHelper :: checkArray ( $this -> newFiles [ 'static' ]) && isset ( $this -> newFiles [ 'dynamic' ]) && ComponentbuilderHelper :: checkArray ( $this -> newFiles [ 'dynamic' ]))
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
// get the bom file
$bom = JFile :: read ( $this -> bomPath );
// first we do the static files
foreach ( $this -> newFiles [ 'static' ] as $static )
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
if ( JFile :: exists ( $static [ 'path' ]))
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
$this -> fileContentStatic [ '###FILENAME###' ] = $static [ 'name' ];
$php = '' ;
if ( ComponentbuilderHelper :: checkFileType ( $static [ 'name' ], 'php' ))
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
$php = " <?php \n " ;
2016-01-30 20:28:43 +00:00
}
2016-02-26 00:20:09 +00:00
$string = JFile :: read ( $static [ 'path' ]);
if ( strpos ( $string , '###BOM###' ) !== false )
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
list ( $wast , $code ) = explode ( '###BOM###' , $string );
$answer = str_replace ( array_keys ( $this -> fileContentStatic ), array_values ( $this -> fileContentStatic ), $php . $bom . $code );
2017-02-09 16:11:10 +00:00
// add custom Code by placeholder if found
$this -> getPlaceHolderKeys ( $static [ 'path' ], $answer );
2016-02-26 00:20:09 +00:00
// add to zip array
$this -> writeFile ( $static [ 'path' ], $answer );
2016-01-30 20:28:43 +00:00
}
else
{
2016-02-26 00:20:09 +00:00
$answer = str_replace ( array_keys ( $this -> fileContentStatic ), array_values ( $this -> fileContentStatic ), $string );
2017-02-09 16:11:10 +00:00
// add custom Code by placeholder if found
$this -> getPlaceHolderKeys ( $static [ 'path' ], $answer );
2016-02-26 00:20:09 +00:00
// add to zip array
$this -> writeFile ( $static [ 'path' ], $answer );
2016-01-30 20:28:43 +00:00
}
2016-02-26 00:20:09 +00:00
$this -> lineCount = $this -> lineCount + substr_count ( $answer , PHP_EOL );
2016-01-30 20:28:43 +00:00
}
2016-02-26 00:20:09 +00:00
}
// now we do the dynamic files
foreach ( $this -> newFiles [ 'dynamic' ] as $view => $files )
{
if ( isset ( $this -> fileContentDynamic [ $view ]) && ComponentbuilderHelper :: checkArray ( $this -> fileContentDynamic [ $view ]))
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
foreach ( $files as $file )
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
if ( $file [ 'view' ] == $view )
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
if ( JFile :: exists ( $file [ 'path' ]))
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
$this -> fileContentStatic [ '###FILENAME###' ] = $file [ 'name' ];
2017-02-01 13:17:04 +00:00
// do some weird stuff to improve the verion and dates being added to the license
$this -> fixLicenseValues ( $file );
2016-02-26 00:20:09 +00:00
$php = '' ;
if ( ComponentbuilderHelper :: checkFileType ( $file [ 'name' ], 'php' ))
{
$php = " <?php \n " ;
}
$string = JFile :: read ( $file [ 'path' ]);
if ( strpos ( $string , '###BOM###' ) !== false )
{
list ( $bin , $code ) = explode ( '###BOM###' , $string );
$answer = str_replace ( array_keys ( $this -> fileContentStatic ), array_values ( $this -> fileContentStatic ), $php . $bom . $code );
$answer = str_replace ( array_keys ( $this -> fileContentDynamic [ $view ]), array_values ( $this -> fileContentDynamic [ $view ]), $answer );
2017-02-09 16:11:10 +00:00
// add custom Code by placeholder if found
$this -> getPlaceHolderKeys ( $file [ 'path' ], $answer , $view );
2016-02-26 00:20:09 +00:00
// add to zip array
$this -> writeFile ( $file [ 'path' ], $answer );
}
else
{
$answer = str_replace ( array_keys ( $this -> fileContentStatic ), array_values ( $this -> fileContentStatic ), $string );
$answer = str_replace ( array_keys ( $this -> fileContentDynamic [ $view ]), array_values ( $this -> fileContentDynamic [ $view ]), $answer );
2017-02-09 16:11:10 +00:00
// add custom Code by placeholder if found
$this -> getPlaceHolderKeys ( $file [ 'path' ], $answer , $view );
2016-02-26 00:20:09 +00:00
// add to zip array
$this -> writeFile ( $file [ 'path' ], $answer );
}
$this -> lineCount = $this -> lineCount + substr_count ( $answer , PHP_EOL );
2016-01-30 20:28:43 +00:00
}
}
}
}
2017-02-01 13:17:04 +00:00
// free up some memory
unset ( $this -> fileContentDynamic [ $view ]);
2016-01-30 20:28:43 +00:00
}
2017-02-01 13:17:04 +00:00
// free up some memory
unset ( $this -> newFiles [ 'dynamic' ]);
2016-02-26 00:20:09 +00:00
// do a final run to update the readme file
2016-10-23 23:05:06 +00:00
$two = 0 ;
2016-02-26 00:20:09 +00:00
foreach ( $this -> newFiles [ 'static' ] as $static )
{
2017-02-02 11:54:07 +00:00
if (( 'README.md' === $static [ 'name' ] || 'README.txt' === $static [ 'name' ]) && $this -> componentData -> addreadme && JFile :: exists ( $static [ 'path' ]))
2016-02-26 00:20:09 +00:00
{
$this -> buildReadMe ( $static [ 'path' ]);
2016-10-23 23:05:06 +00:00
$two ++ ;
}
if ( $two == 2 )
{
2016-01-30 20:28:43 +00:00
break ;
}
2016-02-26 00:20:09 +00:00
}
2017-02-01 13:17:04 +00:00
return true ;
}
return false ;
}
2017-02-09 16:11:10 +00:00
protected function getPlaceHolderKeys ( & $file , & $content , & $view = '' )
{
// check if line has custom code place holder
if ( strpos ( $content , '[CUSTO' . 'MCODE=' ) !== false )
{
if ( ! isset ( $this -> addCustomCodeAt [ $file ]))
{
$this -> addCustomCodeAt [ $file ] = array ();
$this -> addCustomCodeAt [ $file ][ 'ids' ] = array ();
$this -> addCustomCodeAt [ $file ][ 'replace' ] = array ();
$this -> addCustomCodeAt [ $file ][ 'view' ] = $view ;
}
$found = ComponentbuilderHelper :: getAllBetween ( $content , '[CUSTO' . 'MCODE=' , ']' );
if ( ComponentbuilderHelper :: checkArray ( $found ))
{
foreach ( $found as $id )
{
$this -> addCustomCodeAt [ $file ][ 'ids' ][ $id ] = $id ;
}
}
}
}
2017-02-01 13:17:04 +00:00
protected function freeMemory ()
{
// free up some memory
unset ( $this -> newFiles [ 'static' ]);
unset ( $this -> customScriptBuilder );
unset ( $this -> permissionCore );
unset ( $this -> permissionDashboard );
unset ( $this -> componentData -> admin_views );
unset ( $this -> componentData -> site_views );
unset ( $this -> componentData -> custom_admin_views );
unset ( $this -> componentData -> config );
unset ( $this -> joomlaVersionData );
unset ( $this -> langContent );
unset ( $this -> dbKeys );
unset ( $this -> permissionBuilder );
unset ( $this -> layoutBuilder );
unset ( $this -> historyBuilder );
unset ( $this -> aliasBuilder );
unset ( $this -> titleBuilder );
unset ( $this -> customBuilderList );
unset ( $this -> hiddenFieldsBuilder );
unset ( $this -> intFieldsBuilder );
unset ( $this -> dynamicfieldsBuilder );
unset ( $this -> maintextBuilder );
unset ( $this -> customFieldLinksBuilder );
unset ( $this -> setScriptUserSwitch );
unset ( $this -> categoryBuilder );
unset ( $this -> catCodeBuilder );
unset ( $this -> checkboxBuilder );
unset ( $this -> jsonItemBuilder );
unset ( $this -> base64Builder );
unset ( $this -> basicEncryptionBuilder );
unset ( $this -> advancedEncryptionBuilder );
unset ( $this -> getItemsMethodListStringFixBuilder );
unset ( $this -> getItemsMethodEximportStringFixBuilder );
unset ( $this -> selectionTranslationFixBuilder );
unset ( $this -> listBuilder );
unset ( $this -> customBuilder );
unset ( $this -> editBodyViewScriptBuilder );
unset ( $this -> queryBuilder );
unset ( $this -> sortBuilder );
unset ( $this -> searchBuilder );
unset ( $this -> filterBuilder );
unset ( $this -> fieldsNames );
unset ( $this -> siteFields );
unset ( $this -> siteFieldData );
unset ( $this -> customFieldScript );
unset ( $this -> configFieldSets );
unset ( $this -> jsonStringBuilder );
unset ( $this -> importCustomScripts );
unset ( $this -> eximportView );
unset ( $this -> uninstallBuilder );
unset ( $this -> listColnrBuilder );
unset ( $this -> customFieldBuilder );
unset ( $this -> permissionFields );
unset ( $this -> getAsLookup );
unset ( $this -> secondRunAdmin );
unset ( $this -> uninstallScriptBuilder );
unset ( $this -> buildCategories );
unset ( $this -> iconBuilder );
unset ( $this -> validationFixBuilder );
unset ( $this -> targetRelationControl );
unset ( $this -> targetControlsScriptChecker );
unset ( $this -> accessBuilder );
unset ( $this -> tabCounter );
unset ( $this -> linkedAdminViews );
unset ( $this -> uniquekeys );
unset ( $this -> uniquecodes );
$this -> unsetNow ( '_adminViewData' );
$this -> unsetNow ( '_fieldData' );
}
/**
* move the local update server xml file to a remote ftp server
*
* @ return void
*
*/
protected function setUpdateServer ()
{
// move the update server to host
if ( $this -> componentData -> add_update_server && $this -> componentData -> update_server_target == 1 && isset ( $this -> updateServerFileName ) && $this -> dynamicIntegration )
{
$xml_update_server_path = $this -> componentPath . '/' . $this -> updateServerFileName . '.xml' ;
// make sure we have the correct file
if ( JFile :: exists ( $xml_update_server_path ) && isset ( $this -> componentData -> update_server_ftp ))
{
// Get the basic encription.
$basickey = ComponentbuilderHelper :: getCryptKey ( 'basic' );
// Get the encription object.
$basic = new FOFEncryptAes ( $basickey , 128 );
if ( ! empty ( $this -> componentData -> update_server_ftp ) && $basickey && ! is_numeric ( $this -> componentData -> update_server_ftp ) && $this -> componentData -> update_server_ftp === base64_encode ( base64_decode ( $this -> componentData -> update_server_ftp , true )))
{
// basic decript data update_server_ftp.
$this -> componentData -> update_server_ftp = rtrim ( $basic -> decryptString ( $this -> componentData -> update_server_ftp ), " \0 " );
}
// now move the file
$this -> moveFileToFtpServer ( $xml_update_server_path , $this -> componentData -> update_server_ftp );
}
}
}
// link canges made to views into the file license
protected function fixLicenseValues ( $data )
{
2017-02-02 12:17:31 +00:00
// check if these files have its own config data)
if ( isset ( $data [ 'config' ]) && ComponentbuilderHelper :: checkArray ( $data [ 'config' ]) && ( ! isset ( $this -> componentData -> mvc_versiondate ) || $this -> componentData -> mvc_versiondate == 1 ))
2017-02-01 13:17:04 +00:00
{
foreach ( $data [ 'config' ] as $key => $value )
2016-02-26 00:20:09 +00:00
{
2017-02-02 11:54:07 +00:00
if ( '###VERSION###' === $key )
2016-01-30 20:28:43 +00:00
{
2017-02-01 13:17:04 +00:00
// hmm we sould in some way make it known that this version number
// is not in relation the the project but to the file only... any ideas?
// this is the best for now...
if ( 1 == $value )
2016-01-30 20:28:43 +00:00
{
2017-02-01 13:17:04 +00:00
$value = '@first version of this MVC' ;
}
else
{
$value = '@update number ' . $value . ' of this MVC' ;
2016-01-30 20:28:43 +00:00
}
}
2017-02-01 13:17:04 +00:00
$this -> fileContentStatic [ $key ] = $value ;
2016-01-30 20:28:43 +00:00
}
2016-02-26 00:20:09 +00:00
return true ;
2016-01-30 20:28:43 +00:00
}
2017-02-01 13:17:04 +00:00
// else insure to reset to global
$this -> fileContentStatic [ '###CREATIONDATE###' ] = $this -> fileContentStatic [ '###CREATIONDATE###GLOBAL' ];
$this -> fileContentStatic [ '###BUILDDATE###' ] = $this -> fileContentStatic [ '###BUILDDATE###GLOBAL' ];
$this -> fileContentStatic [ '###VERSION###' ] = $this -> fileContentStatic [ '###VERSION###GLOBAL' ];
2016-01-30 20:28:43 +00:00
}
2016-02-26 00:20:09 +00:00
private function buildReadMe ( $path )
2016-10-23 22:48:26 +00:00
{
// set readme data if not set already
if ( ! isset ( $this -> fileContentStatic [ '###LINE_COUNT###' ]) || $this -> fileContentStatic [ '###LINE_COUNT###' ] != $this -> lineCount )
{
$this -> buildReadMeData ();
}
// get the file
$string = JFile :: read ( $path );
// update the file
$answer = str_replace ( array_keys ( $this -> fileContentStatic ), array_values ( $this -> fileContentStatic ), $string );
// add to zip array
$this -> writeFile ( $path , $answer );
2017-02-01 13:17:04 +00:00
}
2016-10-23 22:48:26 +00:00
private function buildReadMeData ()
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
// setup the unrealistic numbers
$folders = $this -> folderCount * 5 ;
$files = $this -> fileCount * 5 ;
$lines = $this -> lineCount * 10 ;
$seconds = $folders + $files + $lines ;
$totalHours = round ( $seconds / 3600 );
$totalDays = round ( $totalHours / 8 );
// setup the more realistic numbers
$debugging = $seconds / 4 ;
$planning = $seconds / 7 ;
$mapping = $seconds / 10 ;
$office = $seconds / 6 ;
$seconds = $folders + $files + $lines + $debugging + $planning + $mapping + $office ;
$actualTotalHours = round ( $seconds / 3600 );
$actualTotalDays = round ( $actualTotalHours / 8 );
$debuggingHours = round ( $debugging / 3600 );
$planningHours = round ( $planning / 3600 );
$mappingHours = round ( $mapping / 3600 );
$officeHours = round ( $office / 3600 );
// the actual time spent
$actualHoursSpent = $actualTotalHours - $totalHours ;
$actualDaysSpent = $actualTotalDays - $totalDays ;
// calculate the projects actual time frame of completion
$projectWeekTime = round ( $actualTotalDays / 5 , 1 );
$projectMonthTime = round ( $actualTotalDays / 24 , 1 );
// set some defaults
$this -> fileContentStatic [ '###LINE_COUNT###' ] = $this -> lineCount ;
$this -> fileContentStatic [ '###FILE_COUNT###' ] = $this -> fileCount ;
$this -> fileContentStatic [ '###FOLDER_COUNT###' ] = $this -> folderCount ;
$this -> fileContentStatic [ '###folders###' ] = $folders ;
$this -> fileContentStatic [ '###files###' ] = $files ;
$this -> fileContentStatic [ '###lines###' ] = $lines ;
$this -> fileContentStatic [ '###seconds###' ] = $seconds ;
$this -> fileContentStatic [ '###totalHours###' ] = $totalHours ;
$this -> fileContentStatic [ '###totalDays###' ] = $totalDays ;
$this -> fileContentStatic [ '###debugging###' ] = $debugging ;
$this -> fileContentStatic [ '###planning###' ] = $planning ;
$this -> fileContentStatic [ '###mapping###' ] = $mapping ;
$this -> fileContentStatic [ '###office###' ] = $office ;
$this -> fileContentStatic [ '###actualTotalHours###' ] = $actualTotalHours ;
$this -> fileContentStatic [ '###actualTotalDays###' ] = $actualTotalDays ;
$this -> fileContentStatic [ '###debuggingHours###' ] = $debuggingHours ;
$this -> fileContentStatic [ '###planningHours###' ] = $planningHours ;
$this -> fileContentStatic [ '###mappingHours###' ] = $mappingHours ;
$this -> fileContentStatic [ '###officeHours###' ] = $officeHours ;
$this -> fileContentStatic [ '###actualHoursSpent###' ] = $actualHoursSpent ;
$this -> fileContentStatic [ '###actualDaysSpent###' ] = $actualDaysSpent ;
$this -> fileContentStatic [ '###projectWeekTime###' ] = $projectWeekTime ;
$this -> fileContentStatic [ '###projectMonthTime###' ] = $projectMonthTime ;
2016-01-30 20:28:43 +00:00
}
2016-02-26 00:20:09 +00:00
private function zipComponent ()
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
// before we zip the component we first need to move it to the git folder if set
if ( ComponentbuilderHelper :: checkString ( $this -> gitPath ))
{
// set the git path
$this -> gitPath = $this -> gitPath . '/com_' . $this -> componentData -> sales_name . '__joomla_' . $this -> joomlaVersion ;
// remove old data
$this -> removeFolder ( $this -> gitPath , true );
// set the new data
JFolder :: copy ( $this -> componentPath , $this -> gitPath , '' , true );
}
// the name of the zip file to create
$this -> filepath = $this -> tempPath . '/' . $this -> componentFolderName . '.zip' ;
// store the current joomla working directory
$joomla = getcwd ();
2016-01-30 20:28:43 +00:00
2016-02-26 00:20:09 +00:00
// we are changing the working directory to the componet temp folder
chdir ( $this -> componentPath );
2016-01-30 20:28:43 +00:00
2016-02-26 00:20:09 +00:00
// the full file path of the zip file
$this -> filepath = JPath :: clean ( $this -> filepath );
2016-01-30 20:28:43 +00:00
2016-02-26 00:20:09 +00:00
// delete an existing zip file (or use an exclusion parameter in JFolder::files()
JFile :: delete ( $this -> filepath );
2016-01-30 20:28:43 +00:00
2016-02-26 00:20:09 +00:00
// get a list of files in the current directory tree
$files = JFolder :: files ( '.' , '' , true , true );
$zipArray = array ();
// setup the zip array
foreach ( $files as $file )
{
$tmp = array ();
$tmp [ 'name' ] = str_replace ( './' , '' , $file );
$tmp [ 'data' ] = JFile :: read ( $file );
$tmp [ 'time' ] = filemtime ( $file );
$zipArray [] = $tmp ;
}
2016-01-30 20:28:43 +00:00
2016-02-26 00:20:09 +00:00
// change back to joomla working directory
chdir ( $joomla );
2016-01-30 20:28:43 +00:00
2016-02-26 00:20:09 +00:00
// get the zip adapter
$zip = JArchive :: getAdapter ( 'zip' );
2016-01-30 20:28:43 +00:00
2016-02-26 00:20:09 +00:00
//create the zip file
if ( $zip -> create ( $this -> filepath , $zipArray ))
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
// now move to backup if zip was made and backup is requered
2016-11-22 05:48:55 +00:00
if ( $this -> backupPath && $this -> dynamicIntegration )
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
JFile :: copy ( $this -> filepath , $this -> backupPath );
2016-01-30 20:28:43 +00:00
}
2016-02-26 00:20:09 +00:00
// move to sales server host
2016-11-22 05:48:55 +00:00
if ( $this -> componentData -> add_sales_server && $this -> dynamicIntegration )
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
// make sure we have the correct file
if ( isset ( $this -> componentData -> sales_server_ftp ))
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
// Get the basic encription.
$basickey = ComponentbuilderHelper :: getCryptKey ( 'basic' );
// Get the encription object.
$basic = new FOFEncryptAes ( $basickey , 128 );
if ( ! empty ( $this -> componentData -> sales_server_ftp ) && $basickey && ! is_numeric ( $this -> componentData -> sales_server_ftp ) && $this -> componentData -> sales_server_ftp === base64_encode ( base64_decode ( $this -> componentData -> sales_server_ftp , true )))
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
// basic decript data update_server_ftp.
$this -> componentData -> sales_server_ftp = rtrim ( $basic -> decryptString ( $this -> componentData -> sales_server_ftp ), " \0 " );
2016-01-30 20:28:43 +00:00
}
2016-02-26 00:20:09 +00:00
// now move the file
$this -> moveFileToFtpServer ( $this -> filepath , $this -> componentData -> sales_server_ftp , $this -> componentSalesName . '.zip' , false );
2016-01-30 20:28:43 +00:00
}
}
2016-02-26 00:20:09 +00:00
// remove the component folder since we are done
if ( $this -> removeFolder ( $this -> componentPath ))
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
return true ;
2016-01-30 20:28:43 +00:00
}
}
2016-02-26 00:20:09 +00:00
return false ;
}
private function moveFileToFtpServer ( $localPath , $clientInput , $remote = null , $removeLocal = true )
{
// get the ftp opbject
$ftp = $this -> getFTP ( $clientInput );
// chack if we are conected
if ( $ftp instanceof JClientFtp && $ftp -> isConnected ())
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
// move the file
if ( $ftp -> store ( $localPath , $remote ))
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
// if moved then remove the file from repository
if ( $removeLocal )
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
JFile :: delete ( $localPath );
2016-01-30 20:28:43 +00:00
}
}
2016-02-26 00:20:09 +00:00
// at the end close the conection
$ftp -> quit ();
2016-01-30 20:28:43 +00:00
}
}
2016-02-26 00:20:09 +00:00
private function getFTP ( $clientInput )
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
$signature = md5 ( $clientInput );
if ( isset ( $this -> FTP [ $signature ]) && $this -> FTP [ $signature ] instanceof JClientFtp )
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
return $this -> FTP [ $signature ];
2016-01-30 20:28:43 +00:00
}
2016-02-26 00:20:09 +00:00
else
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
// make sure we have a string and it is not default or empty
if ( ComponentbuilderHelper :: checkString ( $clientInput ))
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
// turn into vars
parse_str ( $clientInput );
// set options
if ( isset ( $options ) && ComponentbuilderHelper :: checkArray ( $options ))
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
foreach ( $options as $option => $value )
2016-01-30 20:28:43 +00:00
{
2017-02-02 11:54:07 +00:00
if ( 'timeout' === $option )
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
$options [ $option ] = ( int ) $value ;
2016-01-30 20:28:43 +00:00
}
2017-02-02 11:54:07 +00:00
if ( 'type' === $option )
2016-01-30 20:28:43 +00:00
{
2016-02-26 00:20:09 +00:00
$options [ $option ] = ( string ) $value ;
2016-01-30 20:28:43 +00:00
}
}
}
2016-02-26 00:20:09 +00:00
else
{
$options = array ();
}
// get ftp object
if ( isset ( $host ) && $host != 'HOSTNAME' && isset ( $port ) && $port != 'PORT_INT' && isset ( $username ) && $username != 'user@name.com' && isset ( $password ) && $password != 'password' )
{
// load for reuse
$this -> FTP [ $signature ] = JClientFtp :: getInstance ( $host , $port , $options , $username , $password );
return $this -> FTP [ $signature ];
}
2016-01-30 20:28:43 +00:00
}
}
return false ;
}
2017-02-01 13:17:04 +00:00
2017-02-09 16:11:10 +00:00
protected function addCustomCodeViaPlaceholders ( $app )
{
// reset all these
unset ( $this -> placeholders [ '###view###' ]);
unset ( $this -> placeholders [ '###VIEW###' ]);
unset ( $this -> placeholders [ '###View###' ]);
unset ( $this -> placeholders [ '[[[view]]]' ]);
unset ( $this -> placeholders [ '[[[VIEW]]]' ]);
unset ( $this -> placeholders [ '[[[View]]]' ]);
unset ( $this -> placeholders [ '###views###' ]);
unset ( $this -> placeholders [ '###VIEWS###' ]);
unset ( $this -> placeholders [ '###Views###' ]);
unset ( $this -> placeholders [ '[[[views]]]' ]);
unset ( $this -> placeholders [ '[[[VIEWS]]]' ]);
unset ( $this -> placeholders [ '[[[Views]]]' ]);
unset ( $this -> placeholders [ '###SView###' ]);
unset ( $this -> placeholders [ '###sview###' ]);
unset ( $this -> placeholders [ '###SVIEW###' ]);
unset ( $this -> placeholders [ '[[[SView]]]' ]);
unset ( $this -> placeholders [ '[[[sview]]]' ]);
unset ( $this -> placeholders [ '[[[SVIEW]]]' ]);
unset ( $this -> placeholders [ '###SViews###' ]);
unset ( $this -> placeholders [ '###sviews###' ]);
unset ( $this -> placeholders [ '###SVIEWS###' ]);
unset ( $this -> placeholders [ '[[[SViews]]]' ]);
unset ( $this -> placeholders [ '[[[sviews]]]' ]);
unset ( $this -> placeholders [ '[[[SVIEWS]]]' ]);
foreach ( $this -> addCustomCodeAt as $path => $item )
{
if ( ComponentbuilderHelper :: checkString ( $item [ 'view' ]))
{
$this -> placeholders [ '[[[view]]]' ] = $item [ 'view' ];
}
elseif ( isset ( $this -> placeholders [ '[[[view]]]' ]))
{
unset ( $this -> placeholders [ '[[[view]]]' ]);
}
if ( $this -> getCustomCode ( $item [ 'ids' ]))
{
$code = array ();
foreach ( $this -> customCode as $item )
{
$placeholder = $this -> getPlaceHolder ( 2 , $item [ 'id' ]);
$code [ '[CUSTOM' . 'CODE=' . $item [ 'id' ] . ']' ] = $placeholder [ 'start' ] . PHP_EOL . str_replace ( array_keys ( $this -> placeholders ), array_values ( $this -> placeholders ), $item [ 'code' ]) . $placeholder [ 'end' ];
}
// now update the file
$string = JFile :: read ( $path );
$answer = str_replace ( array_keys ( $code ), array_values ( $code ), $string );
$this -> writeFile ( $path , $answer );
}
else
{
$app -> enqueueMessage ( JText :: sprintf ( 'Custom code could not be added to <b>%s</b> <br />Since there where no publish code returned from the database.' , $path ), 'warning' );
}
}
}
2017-02-04 00:22:17 +00:00
protected function addCustomCode ( $app )
2017-02-01 13:17:04 +00:00
{
foreach ( $this -> customCode as $nr => $target )
{
// reset each time per custom code
$fingerPrint = array ();
if ( isset ( $target [ 'hashtarget' ][ 0 ]) && $target [ 'hashtarget' ][ 0 ] > 3
&& isset ( $target [ 'path' ]) && ComponentbuilderHelper :: checkString ( $target [ 'path' ])
&& isset ( $target [ 'hashtarget' ][ 1 ]) && ComponentbuilderHelper :: checkString ( $target [ 'hashtarget' ][ 1 ]))
{
$file = $this -> componentPath . '/' . $target [ 'path' ];
$size = ( int ) $target [ 'hashtarget' ][ 0 ];
$hash = $target [ 'hashtarget' ][ 1 ];
$cut = $size - 1 ;
$found = false ;
$bites = 0 ;
2017-02-04 00:22:17 +00:00
$lineBites = array ();
2017-02-01 13:17:04 +00:00
$replace = array ();
if ( $target [ 'type' ] == 1 && isset ( $target [ 'hashendtarget' ][ 0 ]) && $target [ 'hashendtarget' ][ 0 ] > 0 )
{
$foundEnd = false ;
$sizeEnd = ( int ) $target [ 'hashendtarget' ][ 0 ];
$hashEnd = $target [ 'hashendtarget' ][ 1 ];
$cutEnd = $sizeEnd - 1 ;
}
else
{
// replace to the end of the file
$foundEnd = true ;
}
$counter = 0 ;
// check if file is new structure
if ( JFile :: exists ( $file ))
{
foreach ( new SplFileObject ( $file ) as $lineNumber => $lineContent )
{
2017-02-04 00:22:17 +00:00
// if not found we need to load line bites per line
$lineBites [ $lineNumber ] = ( int ) mb_strlen ( $lineContent , '8bit' );
2017-02-01 13:17:04 +00:00
if ( ! $found )
{
2017-02-04 00:22:17 +00:00
$bites = ( int ) bcadd ( $lineBites [ $lineNumber ], $bites );
2017-02-01 13:17:04 +00:00
}
if ( $found && ! $foundEnd )
{
2017-02-04 00:22:17 +00:00
$replace [] = ( int ) $lineBites [ $lineNumber ];
2017-02-01 13:17:04 +00:00
// we musk keep last three lines to dynamic find target entry
$fingerPrint [ $lineNumber ] = trim ( $lineContent );
// check lines each time if it fits our target
if ( count ( $fingerPrint ) === $sizeEnd && ! $foundEnd )
{
$fingerTest = md5 ( implode ( '' , $fingerPrint ));
if ( $fingerTest === $hashEnd )
{
// we are done here
$foundEnd = true ;
$replace = array_slice ( $replace , 0 , count ( $replace ) - $sizeEnd );
break ;
}
else
{
$fingerPrint = array_slice ( $fingerPrint , - $cutEnd , $cutEnd , true );
}
}
2017-02-04 00:22:17 +00:00
continue ;
2017-02-01 13:17:04 +00:00
}
if ( $found && $foundEnd )
{
2017-02-04 00:22:17 +00:00
$replace [] = ( int ) $lineBites [ $lineNumber ];
2017-02-01 13:17:04 +00:00
}
// we musk keep last three lines to dynamic find target entry
$fingerPrint [ $lineNumber ] = trim ( $lineContent );
// check lines each time if it fits our target
if ( count ( $fingerPrint ) === $size && ! $found )
{
$fingerTest = md5 ( implode ( '' , $fingerPrint ));
if ( $fingerTest === $hash )
{
// we are done here
$found = true ;
// reset in case
$fingerPrint = array ();
// break if it is insertion
if ( $target [ 'type' ] == 2 )
{
break ;
}
}
else
{
$fingerPrint = array_slice ( $fingerPrint , - $cut , $cut , true );
}
}
}
if ( $found )
{
$placeholder = $this -> getPlaceHolder ( $target [ 'type' ], $target [ 'id' ]);
2017-02-09 16:11:10 +00:00
$data = $placeholder [ 'start' ] . PHP_EOL . $target [ 'code' ] . $placeholder [ 'end' ];
2017-02-01 13:17:04 +00:00
if ( $target [ 'type' ] == 2 )
{
// found it now add code from the next line
$this -> addDataToFile ( $file , $data , $bites );
}
elseif ( $target [ 'type' ] == 1 && $foundEnd )
{
// found it now add code from the next line
2017-02-09 16:11:10 +00:00
$this -> addDataToFile ( $file , $data . PHP_EOL , $bites , ( int ) array_sum ( $replace ));
2017-02-01 13:17:04 +00:00
}
else
{
2017-02-04 00:22:17 +00:00
// Load escaped code since the target endhash has changed
$this -> loadEscapedCode ( $file , $target , $lineBites );
2017-02-09 16:11:10 +00:00
$app -> enqueueMessage ( JText :: sprintf ( 'Custom code could not be added to <b>%s</b> please review the file at <b>line %s</b>. This could be due to a change to lines below the custom code.' , $target [ 'path' ], $target [ 'from_line' ]), 'warning' );
2017-02-01 13:17:04 +00:00
}
}
else
{
2017-02-04 00:22:17 +00:00
// Load escaped code since the target hash has changed
$this -> loadEscapedCode ( $file , $target , $lineBites );
2017-02-09 16:11:10 +00:00
$app -> enqueueMessage ( JText :: sprintf ( 'Custom code could not be added to <b>%s</b> please review the file at <b>line %s</b>. This could be due to a change to lines above the custom code.' , $target [ 'path' ], $target [ 'from_line' ]), 'warning' );
2017-02-01 13:17:04 +00:00
}
}
else
{
2017-02-04 00:22:17 +00:00
// Give developer a notice that file is not found.
$app -> enqueueMessage ( JText :: sprintf ( 'File <b>%s</b> could not be found, so the custom code for this file could not be addded.' , $target [ 'path' ]), 'warning' );
2017-02-01 13:17:04 +00:00
}
}
}
}
2017-02-04 00:22:17 +00:00
protected function loadEscapedCode ( $file , $target , $lineBites )
{
// escape the code
2017-02-09 16:11:10 +00:00
$code = explode ( PHP_EOL , $target [ 'code' ]);
$code = PHP_EOL . " // " . implode ( PHP_EOL . " // " , $code ) . PHP_EOL ;
2017-02-04 00:22:17 +00:00
// get place holders
$placeholder = $this -> getPlaceHolder ( $target [ 'type' ], $target [ 'id' ]);
// build the data
2017-02-09 16:11:10 +00:00
$data = $placeholder [ 'start' ] . $code . $placeholder [ 'end' ] . PHP_EOL ;
2017-02-04 00:22:17 +00:00
// get the bites before insertion
$bitBucket = array ();
foreach ( $lineBites as $line => $value )
{
if ( $line < $target [ 'from_line' ])
{
$bitBucket [] = $value ;
}
}
// add to the file
$this -> addDataToFile ( $file , $data , ( int ) array_sum ( $bitBucket ));
}
2017-02-01 13:17:04 +00:00
// Thanks to http://stackoverflow.com/a/16813550/1429677
protected function addDataToFile ( $file , $data , $position , $replace = null )
{
$fpFile = fopen ( $file , " rw+ " );
$fpTemp = fopen ( 'php://temp' , " rw+ " );
$len = stream_copy_to_stream ( $fpFile , $fpTemp ); // make a copy
fseek ( $fpFile , $position ); // move to the position
if ( $replace )
{
$position = bcadd ( $position , $replace );
}
fseek ( $fpTemp , $position ); // move to the position
fwrite ( $fpFile , $data ); // Add the data
stream_copy_to_stream ( $fpTemp , $fpFile ); // @Jack
fclose ( $fpFile ); // close file
fclose ( $fpTemp ); // close tmp
}
2016-01-30 20:28:43 +00:00
}