How can I get my Amazon S3 encoding function to understand subfolders inside buckets? - amazon-s3

I wrote the following function to encode my S3 links so that they handle Amazon's S3 encoding system to protect links. The trouble is that it only works if the file is in the bucket. If I make a subfolder to the bucket and stick the file in there, it's not working. What am I doing wrong?
function encodeS3($sURL,$sAccessKey,$sSecretKey,$nExpireMinutes = 5) {
$sFile = basename($sURL);
$sBucket = basename(str_replace('/' . $sFile,'',$sURL));
$asQuery = array(
'AWSAccessKeyId' => $sAccessKey,
);
$nExpireSecs = absint( $nExpireMinutes ) * 60;
$nExpireSecs = time() + absint( $nExpireSecs );
$asQuery[ 'Expires' ] = $nExpireSecs;
$sAmazonText = "GET\n\n\n{$nExpireSecs}\n/{$sBucket}/{$sFile}";
$asQuery[ 'Signature' ] = urlencode( base64_encode( ( hash_hmac( 'sha1', utf8_encode( $sAmazonText ), $sSecretKey, TRUE ) ) ) );
$s = add_query_arg( $asQuery, "https://s3.amazonaws.com/{$sBucket}/{$sFile}" );
return esc_url($s);
}

I just needed to change the way I was parsing the URL.
function encodeS3($sURL,$sAccessKey,$sSecretKey,$nExpireMinutes = 5) {
/*
$sFile = basename($sURL);
$sBucket = basename(str_replace('/' . $sFile,'',$sURL));
*/
$sURL = str_replace('https://','',$sURL);
$sURL = str_replace('http://','',$sURL);
$sURL = str_replace(urlencode('https://'),'',$sURL);
$sURL = str_replace(urlencode('http://'),'',$sURL);
$asParts = explode('/',$sURL);
array_shift($asParts);
$sBucket = array_shift($asParts);
$sFile = implode('/',$asParts);
$asQuery = array(
'AWSAccessKeyId' => $sAccessKey,
);
$nExpireSecs = absint( $nExpireMinutes ) * 60;
$nExpireSecs = time() + absint( $nExpireSecs );
$asQuery[ 'Expires' ] = $nExpireSecs;
$sAmazonText = "GET\n\n\n{$nExpireSecs}\n/{$sBucket}/{$sFile}";
$asQuery[ 'Signature' ] = urlencode( base64_encode( ( hash_hmac( 'sha1', utf8_encode( $sAmazonText ), $sSecretKey, TRUE ) ) ) );
$s = add_query_arg( $asQuery, "https://s3.amazonaws.com/{$sBucket}/{$sFile}" );
return esc_url($s);
}
BTW, the above uses some functions that are only available in WordPress. If you need straight PHP, you'll have to adjust this.

Related

Prestashop 1.7: product-prices.TPL: where is defined {$product.price_amount}?

I am looking at the file themes/my_theme/templates/catalog/_partials/product-prices.tpl. There, an attempt to show the real price with taxes is made: <span class="price-ttc">{Tools::displayPrice($product.price_amount*$prix_ttc)} TTC </span>.
However, I don't find the property named price_amount in web/controllers/front/ProductController.php:
public function getTemplateVarProduct()
{
$productSettings = $this->getProductPresentationSettings();
// Hook displayProductExtraContent
$extraContentFinder = new ProductExtraContentFinder();
$product = $this->objectPresenter->present($this->product);
$product['id_product'] = (int) $this->product->id;
$product['out_of_stock'] = (int) $this->product->out_of_stock;
$product['new'] = (int) $this->product->new;
$product['id_product_attribute'] = $this->getIdProductAttributeByRequestOrGroup();
$product['minimal_quantity'] = $this->getProductMinimalQuantity($product);
$product['quantity_wanted'] = $this->getRequiredQuantity($product);
$product['extraContent'] = $extraContentFinder->addParams(array('product' => $this->product))->present();
$product['ecotax'] = Tools::convertPrice((float) $product['ecotax'], $this->context->currency, true, $this->context);
$product_full = Product::getProductProperties($this->context->language->id, $product, $this->context);
$product_full = $this->addProductCustomizationData($product_full);
$product_full['show_quantities'] = (bool) (
Configuration::get('PS_DISPLAY_QTIES')
&& Configuration::get('PS_STOCK_MANAGEMENT')
&& $this->product->quantity > 0
&& $this->product->available_for_order
&& !Configuration::isCatalogMode()
);
$product_full['quantity_label'] = ($this->product->quantity > 1) ? $this->trans('Items', array(), 'Shop.Theme.Catalog') : $this->trans('Item', array(), 'Shop.Theme.Catalog');
$product_full['quantity_discounts'] = $this->quantity_discounts;
if ($product_full['unit_price_ratio'] > 0) {
$unitPrice = ($productSettings->include_taxes) ? $product_full['price'] : $product_full['price_tax_exc'];
$product_full['unit_price'] = $unitPrice / $product_full['unit_price_ratio'];
}
$group_reduction = GroupReduction::getValueForProduct($this->product->id, (int) Group::getCurrent()->id);
if ($group_reduction === false) {
$group_reduction = Group::getReduction((int) $this->context->cookie->id_customer) / 100;
}
$product_full['customer_group_discount'] = $group_reduction;
$product_full['title'] = $this->getProductPageTitle();
$presenter = $this->getProductPresenter();
return $presenter->present(
$productSettings,
$product_full,
$this->context->language
);
}
Could you please tell me where is it located?
PrestaShop 1.7 uses Presenters
Your property is defined here:
/src/Adapter/Presenter/Product/ProductLazyArray.php in addPriceInformation method

get table rate shipping data in Woocommerce REST API

I am trying to get all active shipping methods in Woocommerce REST API. How can I achieve this. I am new to woocommerce REST API, Any help is much appreciated.
I want response something like this -
{
"shipping_methods": {
"method_id": "method_title"
}
}
I , finally, come up with the solution. It may help others.
Below is complete code to get all table rate shipping data including shipping zones, shipping methods by zone and rates by zone -
header('Content-type: application/json');
$json_file=file_get_contents('php://input');
$jsonvalue= json_decode($json_file,true);
global $wpdb;
global $woocommerce;
$active_methods = array();
$shipping_methods = $woocommerce->shipping->load_shipping_methods();
//echo "<pre>";print_r($shipping_methods);
foreach ( $shipping_methods as $id => $shipping_method ) {
if ( isset( $shipping_method->enabled ) && 'yes' === $shipping_method->enabled ) {
$data_arr = array( 'title' => $shipping_method->title, 'tax_status' => $shipping_method->tax_status );
if($id=='table_rate'){
$raw_zones = $wpdb->get_results("SELECT zone_id, zone_name, zone_order FROM {$wpdb->prefix}woocommerce_shipping_zones order by zone_order ASC;");
//echo "<pre>";print_r($raw_zones);
$shipping = array();
$shippingarr = array();
foreach ($raw_zones as $raw_zone) {
$zones = new WC_Shipping_Zone($raw_zone->zone_id);
$zone_id = $zones->zone_id;
$zone_name = $zones->zone_name;
$zone_enabled = $zones->zone_enabled;
$zone_type = $zones->zone_type;
$zone_order = $zones->zone_order;
$shipping['zone_id'] = $zone_id;
$shipping['zone_name'] = $zone_name;
$shipping['zone_enabled'] = $zone_enabled;
$shipping['zone_type'] = $zone_type;
$shipping['zone_order'] = $zone_order;
$shipping_methods = $zones->shipping_methods;
foreach($shipping_methods as $shipping_method){
$methodid = $shipping_method["number"];
$raw_rates[$methodid]['rates'] = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}woocommerce_shipping_table_rates WHERE shipping_method_id={$methodid};",ARRAY_A);
}
$shipping['shipping_methods'] = $raw_rates;
$raw_country = $wpdb->get_results("SELECT location_code FROM {$wpdb->prefix}woocommerce_shipping_zone_locations WHERE zone_id={$zone_id};",ARRAY_N);
$shipping['countries'] = $raw_country;
$shippingarr[] = $shipping;
}
$data_arr['shipping_zones'] = $shippingarr;
}
$active_methods[ $id ] = $data_arr;
}
}
if(!empty($shippingarr)){
$result['success']='true';
$result['error']="0";
$result['msg']='Shipping methos found.';
$result['data']=$active_methods;
}else{
$result['success']='true';
$result['error']="0";
$result['msg']='Shipping methos found.';
$result['data']= array();
}
echo json_encode($result); `

Notice: Undefined index: sEcho datatable

I'm having trouble fixing the error Notice: Undefined index: sEcho, I'm using server process script datatable. enter image description here
This is my code of the server_process I'm using:
<?php
/**
* Script: DataTables server-side script for PHP 5.2+ and MySQL 4.1+
* Notes: Based on a script by Allan Jardine that used the old PHP mysql_* functions.
* Rewritten to use the newer object oriented mysqli extension.
* Copyright: 2010 - Allan Jardine (original script)
* 2012 - Kari Söderholm, aka Haprog (updates)
* License: GPL v2 or BSD (3-point)
*/
mb_internal_encoding('UTF-8');
/**
* Array of database columns which should be read and sent back to DataTables. Use a space where
* you want to insert a non-database field (for example a counter or static image)
*/
$aColumns = array( 'id_clien', 'nom_comp_clien', 'exten', 'correo', 'nombre_ofi', 'no_piso', 'id_ofi_c' );
// Indexed column (used for fast and accurate table cardinality)
$sIndexColumn = 'id_clien';
// DB table to use
$sTable = array('clientes' , 'oficinas');
// Database connection information
$gaSql['user'] = 'root';
$gaSql['password'] = '';
$gaSql['db'] = 'sistemacaem';
$gaSql['server'] = 'localhost';
$gaSql['port'] = 3306; // 3306 is the default MySQL port
// Input method (use $_GET, $_POST or $_REQUEST)
$input =& $_GET;
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* If you just want to use the basic configuration for DataTables with PHP server-side, there is
* no need to edit below this line
*/
/**
* Character set to use for the MySQL connection.
* MySQL will return all strings in this charset to PHP (if the data is stored correctly in the database).
*/
$gaSql['charset'] = 'utf8';
/**
* MySQL connection
*/
$db = new mysqli($gaSql['server'], $gaSql['user'], $gaSql['password'], $gaSql['db'], $gaSql['port']);
if (mysqli_connect_error()) {
die( 'Error connecting to MySQL server (' . mysqli_connect_errno() .') '. mysqli_connect_error() );
}
if (!$db->set_charset($gaSql['charset'])) {
die( 'Error loading character set "'.$gaSql['charset'].'": '.$db->error );
}
/**
* Paging
*/
$sLimit = "";
if ( isset( $input['iDisplayStart'] ) && $input['iDisplayLength'] != '-1' ) {
$sLimit = " LIMIT ".intval( $input['iDisplayStart'] ).", ".intval( $input['iDisplayLength'] );
}
/**
* Ordering
*/
$aOrderingRules = array();
if ( isset( $input['iSortCol_0'] ) ) {
$iSortingCols = intval( $input['iSortingCols'] );
for ( $i=0 ; $i<$iSortingCols ; $i++ ) {
if ( $input[ 'bSortable_'.intval($input['iSortCol_'.$i]) ] == 'true' ) {
$aOrderingRules[] =
"`".$aColumns[ intval( $input['iSortCol_'.$i] ) ]."` "
.($input['sSortDir_'.$i]==='asc' ? 'asc' : 'desc');
}
}
}
if (!empty($aOrderingRules)) {
$sOrder = " ORDER BY ".implode(", ", $aOrderingRules);
} else {
$sOrder = "";
}
/**
* Filtering
* NOTE this does not match the built-in DataTables filtering which does it
* word by word on any field. It's possible to do here, but concerned about efficiency
* on very large tables, and MySQL's regex functionality is very limited
*/
$iColumnCount = count($aColumns);
if ( isset($input['sSearch']) && $input['sSearch'] != "" ) {
$aFilteringRules = array();
for ( $i=0 ; $i<$iColumnCount ; $i++ ) {
if ( isset($input['bSearchable_'.$i]) && $input['bSearchable_'.$i] == 'true' ) {
$aFilteringRules[] = "`".$aColumns[$i]."` LIKE '%".$db->real_escape_string( $input['sSearch'] )."%'";
}
}
if (!empty($aFilteringRules)) {
$aFilteringRules = array('('.implode(" OR ", $aFilteringRules).')');
}
}
// Individual column filtering
for ( $i=0 ; $i<$iColumnCount ; $i++ ) {
if ( isset($input['bSearchable_'.$i]) && $input['bSearchable_'.$i] == 'true' && $input['sSearch_'.$i] != '' ) {
$aFilteringRules[] = "`".$aColumns[$i]."` LIKE '%".$db->real_escape_string($input['sSearch_'.$i])."%'";
}
}
if (!empty($aFilteringRules)) {
$sWhere = " WHERE id_ofi_c = id_ofi ".implode(" AND ", $aFilteringRules);
} else {
$sWhere = "WHERE id_ofi_c = id_ofi ";
}
/**
* SQL queries
* Get data to display
*/
$aQueryColumns = array();
foreach ($aColumns as $col) {
if ($col != ' ') {
$aQueryColumns[] = $col;
}
}
$sQuery = "
SELECT SQL_CALC_FOUND_ROWS `".implode("`, `", $aQueryColumns)."`
FROM `".implode("`, `", $sTable)."`".$sWhere.$sOrder.$sLimit;
$rResult = $db->query( $sQuery ) or die($db->error);
// Data set length after filtering
$sQuery = "SELECT FOUND_ROWS()";
$rResultFilterTotal = $db->query( $sQuery ) or die($db->error);
list($iFilteredTotal) = $rResultFilterTotal->fetch_row();
// Total data set length
$sQuery = "SELECT COUNT(`".$sIndexColumn."`) FROM `".implode("`, `",$sTable)."`";
$rResultTotal = $db->query( $sQuery ) or die($db->error);
list($iTotal) = $rResultTotal->fetch_row();
/**
* Output
*/
$output = array(
"sEcho" => intval($input['sEcho']),
"iTotalRecords" => $iTotal,
"iTotalDisplayRecords" => $iFilteredTotal,
"aaData" => array(),
);
while ( $aRow = $rResult->fetch_assoc() ) {
$row = array();
// for ( $i=0 ; $i<$iColumnCount ; $i++ ) {
// if ( $aColumns[$i] == 'version' ) {
// // Special output formatting for 'version' column
// $row[] = ($aRow[ $aColumns[$i] ]=='0') ? '-' : $aRow[ $aColumns[$i] ];
// } elseif ( $aColumns[$i] != ' ' ) {
// // General output
// $row[] = $aRow[ $aColumns[$i] ];
// }
// }
$row[] = $aRow[ $aColumns[0] ];
$row[] = $aRow[ $aColumns[1] ];
$row[] = $aRow[ $aColumns[2] ];
$row[] = $aRow[ $aColumns[3] ];
$row[] = $aRow[ $aColumns[4] ];
$row[] = $aRow[ $aColumns[5] ];
$row[] = $aRow[ $aColumns[6] ];
$output['aaData'][] = $row;
}
echo json_encode( $output );
?>
I'll be very grateful if somebody could help me out.

Rename & Copy Multiple Files (Different names) to One Name With Numbers

how can I rename or copy multiple files (with different name without numbers like "jhf.mp4" "JJHGF.flv" ..) to one name with numbers like (input_01.mp4 input_02 ....) (order by case) by batch file by giving just path of (folder files) to batch file or dropping the files to it (patch file).
-- MEAN USING VARIABLE OR (dropping with %*) .
Note 1: I need this technique for encoding animes with X264 if any other good ideas I'll be happy to hear it.
Note 2: I'm using Windows 10.
I think you can solve this problem using WSHost-scripts. WSHost-system should be preinstalled on any modern Windows computer.
I designed a system of utilities to tackle your problem:
build-mapping-to-normalized-filenames.js
map-filenames.js
cleanup.cmd
before.cmd
after.cmd
You can find source code for 3-4-5 at the bottom of this answer, and for 1-2 - in separate answers (there is a limit of characters per answer).
1 and 2 are workhorses of this system. Powerful but not user-friendly. Yes you can use them as stand-alone utilities if you understand what input they use.
3-4-5 - are glue that bind this system and expose user-friendly controls.
This system is dependent on absolute paths. But all absolute paths are set as variables at the start of 3-4-5 - so if you want to reorganize system - you need change things there and only there.
This is how it should be deployed at filesystem:
folders:
C:\1\ <- this is the root of system
C:\1\aOrig <- folder for original files
C:\1\norm\ <- folder with files that are part of this system + temp folders
C:\1\norm\backend <- place for non-user-friendly utilities
files:
C:\1\norm\backend\build-mapping-to-normalized-filenames.js
C:\1\norm\backend\map-filenames.js
C:\1\norm\after.cmd
C:\1\norm\before.cmd
C:\1\norm\cleanup.cmd
+files: (these are example international filesnames that you can use for playground to check how system works to make yourserf familiar with it)
C:\1\aOrig\English.txt <- test files, you could add unique content to each
C:\1\aOrig\Русский.txt
C:\1\aOrig\العربية.txt
C:\1\aOrig\ܐܪܡܝܐ.txt
C:\1\aOrig\中文.txt
C:\1\aOrig\日本語.txt
How to use it:
You open your console and go to dir **C:\1\norm**
You call programs in this order:
cleanup.cmd
before.cmd
What happened now is that two interesting temp folders are created:
C:\1\norm\bTemp <- here are normalized files.
C:\1\norm\mappingTemp <- it contains a file with mapping between original and normalized names.
What you must do now - is to process files in C:\1\norm\bTemp - that special processing you mentioned before. Right now for the purposes of learning, you can manually change extensions and contents.
after.cmd
cleanup.cmd
And that's it.
So, if we condence it that's your typical session here, plain and simple -
cleanup.cmd
before.cmd
..do your stuff with files at "C:\1\norm\bTemp"...
after.cmd
cleanup.cmd
Also, you don't need command line to use those - you can open **C:\1\norm** in Explorer and double click those utilities in the order that I explained above - cleanup-before-(..manually do your work with bTemp..)-after-cleanup
Listing for program cleanup.cmd :
#ECHO OFF
:: name of this script...
:: useful for debugging...
SET me=%~nx0
:: aOrig - directory that contains source files...
:: bTemp - temporary working directory...
:: mTemp - temporary directory for mapping.txt...
SET aOrig=C:\1\aOrig
SET bTemp=C:\1\norm\bTemp
SET mTemp=C:\1\norm\mappingTemp
:: Removing temporary folders...
:: Be warned - this RD is working
:: in quiet mode /Q - so it wouldn't ask you politely
:: about del y/n - thus, please make shure that
:: %aOrig% doesn't point to anything
:: important for your personal data or system...
IF EXIST "%bTemp%" RD /S /Q "%bTemp%"
IF EXIST "%mTemp%" RD /S /Q "%mTemp%"
IF %ERRORLEVEL% NEQ 0 (
ECHO Script %me% failed on step cleanup-1: [Removing temporary folders]...
ECHO Error: %ERRORLEVEL%
EXIT /B 1
)
:: Successfully finished
ECHO.
ECHO Script %me% successfully finished!
Listing for program before.cmd :
#ECHO OFF
:: name of this script...
:: useful for debugging...
SET me=%~nx0
:: aOrig - directory that contains original files...
:: bTemp - temporary working directory...
:: mTemp - temporary directory for mapping.txt...
SET aOrig=C:\1\aOrig
SET bTemp=C:\1\norm\bTemp
SET mTemp=C:\1\norm\mappingTemp
:: scriptBuild - name of .js-script for building a map
:: from original to normalized filenames...
:: scriptMapFi - name of .js-script interpreting
:: mapping file that was build by scriptBuild...
:: mappingFile - path for file that will contain mapping between
:: original filenames and normalized filenames...
SET scriptBuild=C:\1\norm\backend\build-mapping-to-normalized-filenames.js
SET scriptMapFi=C:\1\norm\backend\map-filenames.js
SET mappingFile=C:\1\norm\mappingTemp\mapping.txt
:: creating temporary folders...
IF NOT EXIST "%bTemp%" MKDIR "%bTemp%"
IF NOT EXIST "%mTemp%" MKDIR "%mTemp%"
IF %ERRORLEVEL% NEQ 0 (
ECHO Script %me% failed on step before-1: [Creating temporary folders]...
ECHO Error: %ERRORLEVEL%
EXIT /B 1
)
:: now we run build-mapping-to-normalized-filenames.js ...
:: that //U thing is important...
CSCRIPT //U //NoLogo "%scriptBuild%" "%aOrig%" 0 1 > "%mappingFile%"
IF %ERRORLEVEL% NEQ 0 (
ECHO Script %me% failed on step before-2: [Building a list of normalized filenames]...
ECHO Error: %ERRORLEVEL%
EXIT /B 1
)
:: now we run map-filenames.js ...
:: that //U thing is important...
CSCRIPT //U //NoLogo "%scriptMapFi%" "%aOrig%" "%bTemp%" /NotTraining < "%mappingFile%"
IF %ERRORLEVEL% NEQ 0 (
ECHO Script %me% failed on step before-3: [Copy files while simultaneously changing their names to normalised form]...
ECHO Error: %ERRORLEVEL%
EXIT /B 1
)
:: Successfully finished
ECHO.
ECHO Script %me% successfully finished!
Listing for program after.cmd :
#ECHO OFF
:: name of this script...
:: useful for debugging...
SET me=%~nx0
:: aOrig - directory that contains original files...
:: bTemp - temporary working directory...
:: mTemp - temporary directory for mapping.txt...
SET aOrig=C:\1\aOrig
SET bTemp=C:\1\norm\bTemp
SET mTemp=C:\1\norm\mappingTemp
:: scriptBuild - name of .js-script for building a map
:: from original to normalized filenames...
:: scriptMapFi - name of .js-script interpreting
:: mapping file that was build by scriptBuild...
:: mappingFile - path for file that will contain mapping between
:: original filenames and normalized filenames...
SET scriptBuild=C:\1\norm\backend\build-mapping-to-normalized-filenames.js
SET scriptMapFi=C:\1\norm\backend\map-filenames.js
SET mappingFile=C:\1\norm\mappingTemp\mapping.txt
:: Removing files in original folder...
:: Not recursive
:: Be warned - this DEL is working
:: in quiet mode /Q - so it wouldn't ask you politely
:: about del y/n - thus, please make shure that
:: %aOrig% doesn't point to anything
:: important for your personal data or system...
IF EXIST "%aOrig%" DEL /Q "%aOrig%"
IF %ERRORLEVEL% NEQ 0 (
ECHO Script %me% failed on step after-1: [Removing files from original folder]...
ECHO Error: %ERRORLEVEL%
EXIT /B 1
)
:: now we run map-filenames.js ...
:: that //U thing is important...
CSCRIPT //U //NoLogo "%scriptMapFi%" "%bTemp%" "%aOrig%" /NotTraining /MapFrom2To1 /ResultExtension:2 /FuzzyExtensionsFrom < "%mappingFile%"
IF %ERRORLEVEL% NEQ 0 (
ECHO Script %me% failed on step after-2: [Copy files while simultaneously changing their names to normalised form]...
ECHO Error: %ERRORLEVEL%
EXIT /B 1
)
:: Successfully finished
ECHO.
ECHO Script %me% successfully finished!
Listing for program build-mapping-to-normalized-filenames.js :
// - - - - -
// #magicVars #config
// Purpose of basicOptions: organize set of most basic settings
// into a compact object package
var basicOptions = {
// Fist things first -
// "scriptName" will be important for error messages.
// Because when you debug a pipeline of scripts, it is always
// crucial to know - which program in pipeline of 10 utilities
// throws that cryptic stderr message "error: not enough arguments".
// I mean huh? Was that calc-tool.js? Or sort-tool.js? Go figure...
scriptName: WScript.ScriptName.toString(),
// What kind of End Of Line sequence
// (they call it New Line sometimes too)
// you prefer when using outputToolbox?
eolStdOut: '\r\n',
eolStdErr: '\r\n',
// Those are all possible errorCodes that this script
// was designed to fail with.
// You can define other error codes.
// Those SHOULD be integer (not strings).
// Code noErrors = 0 is indication that script finished without errors.
errorCodes: {
noErrors: 0,
badArguments: 1,
badGettingFileList: 2
}
};
// - - - - -
// thisOptions
// Purpose of thisOptions: organize set of hard-coded
// normalisation settings
// into a compact object package
var thisOptions = {
normNameBefore: 'input_',
normNameAfter: ''
}
// - - - - -
// outputToolbox depends on
// basicOptions && WScript
// Purpose of outputToolbox: organize in one group
// functions that are used to
// output chars or messages to stdout or stderr
var outputToolbox = {
// Syntactic sugar for printing exact set of chars to stdout.
print: function( data ) {
// For this script to output UTF characters correctly, program must
// run under /U switch - like
// cscript /U //NoLogo program-name-here.js arg1 arg2
WScript.StdOut.Write( data );
},
// Syntactic sugar for printing one line to stdout.
// terminated with your preferred line-terminator.
printLine: function( data ) {
outputToolbox.print( data );
outputToolbox.print( basicOptions.eolStdOut );
},
// Syntactic sugar for printing exact set of chars to stderr.
printErr: function( data ) {
WScript.StdErr.Write( data );
},
// Syntactic sugar for printing one line to stderr
// terminated with your preferred line-terminator.
printErrLine: function( data ) {
outputToolbox.printErr( data );
outputToolbox.printErr( basicOptions.eolStdErr );
},
// Syntactic sugar for printing one line to stderr
// prepended with meaningful script name (that is useful for debug)
// terminated with your preferred line-terminator.
printErrMessage: function( data ) {
outputToolbox.printErr( basicOptions.scriptName + ' failed' );
outputToolbox.printErr( data );
outputToolbox.printErr( basicOptions.eolStdErr );
},
// Syntactic sugar for printing one line to stderr
// prepended with meaningful script name (that is useful for debug)
// terminated with your preferred line-terminator.
printErrWarning: function( data ) {
outputToolbox.printErr( 'Warning for ' + basicOptions.scriptName + ': ' );
outputToolbox.printErr( data );
outputToolbox.printErr( basicOptions.eolStdErr );
},
// Syntactic sugar for printing Error objects
// catched by throw...catch construction
printErrCatchedErr: function( e ) {
outputToolbox.printErrMessage(
' - catched error details - ' + e.name + ': ' + e.message
);
}
};
// - - - - -
// flowToolbox depends on
// WScript
// Purpose of flowToolbox: organize in one group
// functions that are used to
// control general flow of program
var flowToolbox = {
// Shortcut to kill this script.
// When invoked it stops execution.
die: function ( code ) {
if ( typeof code === 'undefined' ) {
code = 0;
}
WScript.Quit(code);
}
};
// - - - - -
// Here is a cleaner alternative: we pollute only name $b.
// Not so easy to type but later, you can easily find all code calls
// dependant on functions from 'basis'.
// '$b' stands for 'library-b' or more exactly - "library named 'basis'"
var $b = {};
$b.print = outputToolbox.print;
$b.printLine = outputToolbox.printLine;
$b.printErr = outputToolbox.printErr;
$b.printErrLine = outputToolbox.printErrLine;
$b.printErrMessage = outputToolbox.printErrMessage;
$b.printErrWarning = outputToolbox.printErrWarning;
$b.die = flowToolbox.die;
// ^ You can use those as functions now
// - - - - -
// $fileListToolbox
// depends on WScript && ActiveXObject( "Scripting.FileSystemObject" ) && $b
var $fileListToolbox = {
/*
* Input:
* any gibberish that is acceptable
* for your local version of
* Scripting.FileSystemObject
* - like
* getFileListForFolder( 'C:\' );
* getFileListForFolder( 'C:\abc' );
* getFileListForFolder( './' );
* getFileListForFolder( './abc/../abc/..' );
*
* Output:
* aFileList with format:
* empty array
* or
* array of oFileData
* oFileData has format:
* {
* fileNameBase: ...[string],
* fileNameExtension: ...[string],
* parentAbsolutePath: ...[string]
* }
*/
getFileListForFolder: function( folderSpec )
{
var aResult = [];
var fso = new ActiveXObject( "Scripting.FileSystemObject" );
if ( !fso.FolderExists( folderSpec ) ) {
$b.printErrMessage(' folder="' + folderSpec + '" doesn\'t exist');
$b.die( basicOptions.errorCodes.badGettingFileList );
}
var folder = fso.GetFolder( folderSpec );
var files = new Enumerator( folder.files );
for ( ; !files.atEnd(); files.moveNext() ) {
var thisFileItem = files.item();
aResult.push({
fileNameBase: fso.GetBaseName( thisFileItem ),
fileNameExtension: fso.GetExtensionName( thisFileItem ),
parentAbsolutePath: (
fso.GetParentFolderName(
fso.GetAbsolutePathName( thisFileItem )
)
)
});
}
return( aResult );
},
/*
* Purpose:
* Sort files by fileNameBase
*
* Input:
* aFileList
* - format is the same
* as for function $fileListToolbox.getFileListForFolder
*
* Output:
* - format is the same
* as for function $fileListToolbox.getFileListForFolder
*/
sortFileListByFileNameBaseAsc: function( aFileList ) {
var fSort = function( a, b ) {
if ( a.fileNameBase > b.fileNameBase ) {
return 1;
}
if ( a.fileNameBase < b.fileNameBase ) {
return -1;
}
return 0;
}
return aFileList.sort( fSort );
},
/*
* Purpose:
* Tool for displaying contents of fileList
*
* Input:
* aFileList
* - format is the same
* as for function $fileListToolbox.getFileListForFolder
*
* Sideeffects:
* Prints aFileList to the stdout stream
*/
printFileList: function( aFileList, callbackPrintLine ) {
if ( typeof callbackPrintLine === 'undefined' ) {
return;
}
var i;
var L = aFileList.length;
var elem;
for ( i = 0; i < L; i++ ) {
elem = aFileList[i];
callbackPrintLine();
callbackPrintLine( 'i: ' + i );
callbackPrintLine( 'fileNameBase: ' + elem.fileNameBase );
callbackPrintLine( 'fileNameExtension: ' + elem.fileNameExtension );
callbackPrintLine( 'parentAbsolutePath: ' + elem.parentAbsolutePath );
}
}
};
/*
// basic test:
$fileListToolbox.printFileList(
$fileListToolbox.sortFileListByFileNameBaseAsc(
$fileListToolbox.getFileListForFolder( 'bTmp' )
),
$b.printLine
);
*/
// - - - - -
// $mappingEngine
var $mappingEngine = {
// this is a relic from a more complex fileformat...
printHeader: function(
functionPrintChars
) {
},
printBasicFilePair: function(
functionPrintChars,
aFileNameBase, aFileNameExtension,
bFileNameBase, bFileNameExtension
) {
var eol = '\r\n';
if ( aFileNameBase.match( /[\r\n]/ ) !== null ) {
throw new Error(
'error: bad input: aFileNameBase contains end of line symbols'
);
}
if ( bFileNameBase.match( /[\r\n]/ ) !== null ) {
throw new Error(
'error: bad input: bFileNameBase contains end of line symbols'
);
}
if ( aFileNameExtension.match( /[\r\n]/ ) !== null ) {
throw new Error(
'error: bad input: aFileNameExtension contains end of line symbols'
);
}
if ( bFileNameExtension.match( /[\r\n]/ ) !== null ) {
throw new Error(
'error: bad input: bFileNameExtension contains end of line symbols'
);
}
var ar = [
'id:1',
'baseName:' + aFileNameBase,
'extensionName:' + aFileNameExtension,
'id:2',
'baseName:' + bFileNameBase,
'extensionName:' + bFileNameExtension,
':',
''
];
functionPrintChars( ar.join( eol ) );
}
};
/*
//basic test:
$mappingEngine.printHeader( $b.print );
$mappingEngine.printBasicFilePair( $b.print, 'abcdef', 'ext', 'input_001', 'txt' );
$mappingEngine.printBasicFilePair( $b.print, 'ghijkl', 'jpg', 'input_002', 'png' );
*/
// it should print to output:
/*
id:1
baseName:abcdef
extensionName:ext
id:2
baseName:input_001
extensionName:txt
:
id:1
baseName:ghijkl
extensionName:jpg
id:2
baseName:input_002
extensionName:png
:
*/
// - - - - -
function generateFAddLeadingZeroes( minimumLength, startFrom ) {
if ( typeof minimumLength === 'undefined' ) {
minimumLength = 0;
}
if ( typeof startFrom === 'undefined' ) {
startFrom = 0;
}
minimumLength = parseInt( minimumLength ) - 1;
startFrom = parseInt( startFrom );
var fAddLeadingZeroes = function( i, L ) {
i += startFrom;
L += startFrom - 1;
var sResult = i.toString();
if ( minimumLength > 0 ) {
var level = 0;
var tmpL = L;
while (
( tmpL = parseInt( tmpL / 10 ) ) >= 1
) {
++level;
}
level = Math.max( level, minimumLength );
var iLength = sResult.length;
while ( iLength <= level-- ) {
sResult = '0' + sResult;
}
}
return sResult;
}
return fAddLeadingZeroes;
}
// - - - - -
var $thisArguments = {
getArgumentsObj: function() {
return WScript.Arguments;
// mockup for tests in browser
/*
var testArr = [1,2,3,4,5];
var mockupArguments = function( i ) {
return testArr[i];
};
mockupArguments.length = testArr.length;
return mockupArguments;
*/
},
printErrorMessageAndDie: function( meaningfulPart ) {
$b.printErrMessage(
' - problem when ' +
'parsing command-line arguments (options): ' +
''
);
$b.die( basicOptions.errorCodes.badArguments );
},
getArgumentsDummy: function() {
return {
folder: 'C:\abc',
minNOfDigits: 0,
countStart: 1
};
},
print: function( argumentsObject ) {
$b.printErrLine( 'folder: ' + argumentsObject.folder );
$b.printErrLine( 'minNOfDigits: ' + argumentsObject.minNOfDigits );
$b.printErrLine( 'countStart: ' + argumentsObject.countStart );
},
// We don't use any flags it this script...
/*
isThereAFlagInArguments: function( inString ) {
var normalizedEthalon = inString.toString().toLowerCase();
var objArgs = $thisArguments.getArgumentsObj();
var i;
var L = objArgs.length;
for ( i = 2; i < L; i++ ) {
var normalizedArgument = objArgs( i ).toString().toLowerCase();
if ( normalizedEthalon === normalizedArgument ) {
return true;
}
}
return false;
},
*/
getArguments: {
folder: function() {
var rR = '';
var objArgs = $thisArguments.getArgumentsObj();
if ( objArgs.length < 1 ) {
$b.printErrMessage(
' - reason: not enough arguments, ' +
'you MUST to provide at least 1 argument, ' +
'but ammount of arguments you provided ' +
'only: ' + objArgs.length
);
$b.die( basicOptions.errorCodes.badArguments );
}
rR = objArgs(0);
var fso = new ActiveXObject("Scripting.FileSystemObject");
rR = fso.GetAbsolutePathName( rR );
return rR;
},
minNOfDigits: function() {
var rR = '0';
var objArgs = $thisArguments.getArgumentsObj();
if ( objArgs.length >= 2 ) {
rR = objArgs(1);
}
var intRR = parseInt( rR );
// test for NaN
if ( intRR !== intRR ) {
$b.printErrMessage(
' - reason: bad argument 2, ' +
'you MUST to provide non-negative integer, ' +
'but you provided non-integer: ' +
'[' + ( typeof rR ) + ']' +
' "' + rR + '"' +
''
);
$b.die( basicOptions.errorCodes.badArguments );
}
// test for negative
if ( intRR < 0 ) {
$b.printErrMessage(
' - reason: bad argument 2, ' +
'you MUST to provide non-negative integer, ' +
'but you provided negtive integer: ' +
'[' + ( typeof rR ) + ']' +
' "' + rR + '"' +
''
);
$b.die( basicOptions.errorCodes.badArguments );
}
rR = intRR;
return rR;
},
countStart: function() {
var rR = '1';
var objArgs = $thisArguments.getArgumentsObj();
if ( objArgs.length >= 3 ) {
rR = objArgs(2);
}
var intRR = parseInt( rR );
// test for NaN
if ( intRR !== intRR ) {
$b.printErrMessage(
' - reason: bad argument 3, ' +
'you MUST to provide non-negative integer, ' +
'but you provided non-integer: ' +
'[' + ( typeof rR ) + ']' +
' "' + rR + '"' +
''
);
$b.die( basicOptions.errorCodes.badArguments );
}
// test for negative
if ( intRR < 0 ) {
$b.printErrMessage(
' - reason: bad argument 3, ' +
'you MUST to provide non-negative integer, ' +
'but you provided negtive integer: ' +
'[' + ( typeof rR ) + ']' +
' "' + rR + '"' +
''
);
$b.die( basicOptions.errorCodes.badArguments );
}
rR = intRR;
return rR;
}
},
getArgumentsAll: function() {
var $get = $thisArguments.getArguments;
var rR = {
folder: $get.folder(),
minNOfDigits: $get.minNOfDigits(),
countStart: $get.countStart()
};
return rR;
}
};
var $a = $thisArguments;
// - - - - -
function main() {
var $inputOptions = $a.getArgumentsAll();
$b.printErrLine();
$b.printErrLine(
'Arguments for ' + basicOptions.scriptName +
' are interpreted this way:'
);
$a.print( $inputOptions );
$b.printErrLine();
try {
var aFileList = $fileListToolbox.getFileListForFolder( $inputOptions.folder );
} catch (e) {
$b.printErrMessage(
' - problems while trying ' +
'to get list of files from folder: ' +
$inputOptions.folder
);
$b.die( basicOptions.errorCodes.badGettingFileList );
return;
}
aFileList = $fileListToolbox.sortFileListByFileNameBaseAsc( aFileList );
// addLeadingZeroes
// is a function now.
// You can see what arguments it requires
// and output it produces in source for
// generateFAddLeadingZeroes
// function.
var addLeadingZeroes = generateFAddLeadingZeroes(
$inputOptions.minNOfDigits,
$inputOptions.countStart
);
var normNameBefore = thisOptions.normNameBefore;
var normNameAfter = thisOptions.normNameAfter;
var i;
var L = aFileList.length;
for ( i = 0; i < L; i++ ) {
var elem = aFileList[i];
var aBase = elem.fileNameBase;
var aExtension = elem.fileNameExtension;
var count = addLeadingZeroes( i, L );
var bBase = normNameBefore + count + normNameAfter;
var bExtension = aExtension;
$mappingEngine.printBasicFilePair(
$b.print,
aBase, aExtension,
bBase, bExtension
);
}
$b.printErr( 'Script ' + basicOptions.scriptName + ' - finished!' );
};
main();
Listing for program map-filenames.js :
// - - - - -
// #magicVars #config
// Purpose of basicOptions: organize set of most basic settings
// into a compact object package
var basicOptions = {
// Fist things first -
// "scriptName" will be important for error messages.
// Because when you debug a pipeline of scripts, it is always
// crucial to know - which program in pipeline of 10 utilities
// throws that cryptic stderr message "error: not enough arguments".
// I mean huh? Was that calc-tool.js? Or sort-tool.js? Go figure...
scriptName: WScript.ScriptName.toString(),
// What kind of End Of Line sequence
// (they call it New Line sometimes too)
// you prefer when using outputToolbox?
eolStdOut: '\r\n',
eolStdErr: '\r\n',
// Those are all possible errorCodes that this script
// was designed to fail with.
// You can define other error codes.
// Those SHOULD be integer (not strings).
// Code noErrors = 0 is indication that script finished without errors.
errorCodes: {
noErrors: 0,
badArguments: 1,
badCopy: 2,
badParsing: 3,
badGettingFileList: 4
}
};
// - - - - -
// - - - - -
// outputToolbox depends on
// basicOptions && WScript
// Purpose of outputToolbox: organize in one group
// functions that are used to
// output chars or messages to stdout or stderr
var outputToolbox = {
// Syntactic sugar for printing exact set of chars to stdout.
print: function( data ) {
// For this script to output UTF characters correctly, program must
// run under /U switch - like
// cscript /U //NoLogo program-name-here.js arg1 arg2
WScript.StdOut.Write( data );
},
// Syntactic sugar for printing one line to stdout.
// terminated with your preferred line-terminator.
printLine: function( data ) {
outputToolbox.print( data );
outputToolbox.print( basicOptions.eolStdOut );
},
// Syntactic sugar for printing exact set of chars to stderr.
printErr: function( data ) {
WScript.StdErr.Write( data );
},
// Syntactic sugar for printing one line to stderr
// terminated with your preferred line-terminator.
printErrLine: function( data ) {
outputToolbox.printErr( data );
outputToolbox.printErr( basicOptions.eolStdErr );
},
// Syntactic sugar for printing one line to stderr
// prepended with meaningful script name (that is useful for debug)
// terminated with your preferred line-terminator.
printErrMessage: function( data ) {
outputToolbox.printErr( basicOptions.scriptName + ' failed' );
outputToolbox.printErr( data );
outputToolbox.printErr( basicOptions.eolStdErr );
},
// Syntactic sugar for printing one line to stderr
// prepended with meaningful script name (that is useful for debug)
// terminated with your preferred line-terminator.
printErrWarning: function( data ) {
outputToolbox.printErr( 'Warning for ' + basicOptions.scriptName + ': ' );
outputToolbox.printErr( data );
outputToolbox.printErr( basicOptions.eolStdErr );
},
// Syntactic sugar for printing Error objects
// catched by throw...catch construction
printErrCatchedErr: function( e ) {
outputToolbox.printErrMessage(
' - catched error details - ' + e.name + ': ' + e.message
);
}
};
// - - - - -
// flowToolbox depends on
// WScript
// Purpose of flowToolbox: organize in one group
// functions that are used to
// control general flow of program
var flowToolbox = {
// Shortcut to kill this script.
// When invoked it stops execution.
die: function ( code ) {
if ( typeof code === 'undefined' ) {
code = 0;
}
WScript.Quit(code);
}
};
// - - - - -
// Here is a cleaner alternative: we pollute only name $b.
// Not so easy to type but later, you can easily find all code calls
// dependant on functions from 'basis'.
// '$b' stands for 'library-b' or more exactly - "library named 'basis'"
var $b = {};
$b.print = outputToolbox.print;
$b.printLine = outputToolbox.printLine;
$b.printErr = outputToolbox.printErr;
$b.printErrLine = outputToolbox.printErrLine;
$b.printErrMessage = outputToolbox.printErrMessage;
$b.printErrWarning = outputToolbox.printErrWarning;
$b.die = flowToolbox.die;
// ^ You can use those as functions now
// - - - - -
// $fileListToolbox
// depends on WScript && ActiveXObject( "Scripting.FileSystemObject" ) && $b
var $fileListToolbox = {
/*
* Input:
* any gibberish that is acceptable
* for your local version of
* Scripting.FileSystemObject
* - like
* getFileListForFolder( 'C:\' );
* getFileListForFolder( 'C:\abc' );
* getFileListForFolder( './' );
* getFileListForFolder( './abc/../abc/..' );
*
* Output:
* aFileList with format:
* empty array
* or
* array of oFileData
* oFileData has format:
* {
* fileNameBase: ...[string],
* fileNameExtension: ...[string],
* parentAbsolutePath: ...[string]
* }
*/
getFileListForFolder: function( folderSpec )
{
var aResult = [];
var fso = new ActiveXObject( "Scripting.FileSystemObject" );
if ( !fso.FolderExists( folderSpec ) ) {
$b.printErrMessage(' folder="' + folderSpec + '" doesn\'t exist');
$b.die( basicOptions.errorCodes.badGettingFileList );
}
var folder = fso.GetFolder( folderSpec );
var files = new Enumerator( folder.files );
for ( ; !files.atEnd(); files.moveNext() ) {
var thisFileItem = files.item();
aResult.push({
fileNameBase: fso.GetBaseName( thisFileItem ),
fileNameExtension: fso.GetExtensionName( thisFileItem ),
parentAbsolutePath: (
fso.GetParentFolderName(
fso.GetAbsolutePathName( thisFileItem )
)
)
});
}
return( aResult );
},
/*
* Purpose:
* Sort files by fileNameBase
*
* Input:
* aFileList
* - format is the same
* as for function $fileListToolbox.getFileListForFolder
*
* Output:
* - format is the same
* as for function $fileListToolbox.getFileListForFolder
*/
sortFileListByFileNameBaseAsc: function( aFileList ) {
var fSort = function( a, b ) {
if ( a.fileNameBase > b.fileNameBase ) {
return 1;
}
if ( a.fileNameBase < b.fileNameBase ) {
return -1;
}
return 0;
}
return aFileList.sort( fSort );
},
/*
Output:
false
when no results
oFileData
when result found
*/
getAnyFileWithBaseName: function( baseName, aFileList ) {
var i;
var L = aFileList.length;
for ( i = 0; i < L; i++ ) {
var a = aFileList[i];
if ( a.fileNameBase === baseName ) {
return a;
}
}
return false;
},
/*
* Purpose:
* Tool for displaying contents of fileList
*
* Input:
* aFileList
* - format is the same
* as for function $fileListToolbox.getFileListForFolder
*
* Sideeffects:
* Prints aFileList to the stdout stream
*/
printFileList: function( aFileList, callbackPrintLine ) {
if ( typeof callbackPrintLine === 'undefined' ) {
return;
}
var i;
var L = aFileList.length;
var elem;
for ( i = 0; i < L; i++ ) {
elem = aFileList[i];
callbackPrintLine();
callbackPrintLine( 'i: ' + i );
callbackPrintLine( 'fileNameBase: ' + elem.fileNameBase );
callbackPrintLine( 'fileNameExtension: ' + elem.fileNameExtension );
callbackPrintLine( 'parentAbsolutePath: ' + elem.parentAbsolutePath );
}
}
};
/*
// basic test:
$fileListToolbox.printFileList(
$fileListToolbox.sortFileListByFileNameBaseAsc(
$fileListToolbox.getFileListForFolder( 'bTmp' )
),
$b.printLine
);
*/
/*
// test for fuzzy search only by file base name:
$fileListToolbox.printFileList(
$fileListToolbox.sortFileListByFileNameBaseAsc(
$fileListToolbox.getFileListForFolder( 'bTmp' )
),
$b.printLine
);
var fuzzy = $fileListToolbox.getAnyFileWithBaseName(
'input_1',
$fileListToolbox.getFileListForFolder( 'bTmp' )
);
$b.printLine( 'fuzzy.fileNameBase: ' + fuzzy.fileNameBase );
$b.printLine( 'fuzzy.fileNameExtension: ' + fuzzy.fileNameExtension );
*/
// $streamToolbox
var $streamToolbox = {
// when end of line returns '' (aka empty string)
getChar: function() {
if ( WScript.StdIn.AtEndOfStream ) {
return '';
}
return WScript.StdIn.Read(1);
},
// tests show that for Windows 7 it understands terminators
// CRLF or LF-only
// when end of line returns '' (aka empty string)
getLine: function() {
if ( WScript.StdIn.AtEndOfStream ) {
return '';
}
return WScript.StdIn.ReadLine();
}
}
var $s = $streamToolbox;
// it could be used like that:
/*
var piece;
while ( ( piece = $s.getLine() ) !== '' ) {
$b.printLine( 'piece: ' + '>' + piece + '<' );
}
*/
// $thisArguments
var $thisArguments = {
getArgumentsObj: function() {
return WScript.Arguments;
// mockup for tests in browser
/*
var testArr = [1,2,3,4,5];
var mockupArguments = function( i ) {
return testArr[i];
};
mockupArguments.length = testArr.length;
return mockupArguments;
*/
},
printErrorMessageAndDie: function( meaningfulPart ) {
$b.printErrMessage(
' - problem when ' +
'parsing command-line arguments (options): ' +
''
);
$b.die( basicOptions.errorCodes.badArguments );
},
getArgumentsDummy: function() {
return {
direction: 'from-id-2-to-id-1',
resultExtension: 'auto',
folderFrom: 'C:\abc',
folderTo: 'D:\abc',
mode: 'training',
modeForExtensionFrom: 'strict'
};
},
print: function( argumentsObject ) {
$b.printErrLine( 'folderFrom: ' + argumentsObject.folderFrom );
$b.printErrLine( 'folderTo: ' + argumentsObject.folderTo );
$b.printErrLine( 'direction: ' + argumentsObject.direction );
$b.printErrLine( 'resultExtension: ' + argumentsObject.resultExtension );
$b.printErrLine( 'mode: ' + argumentsObject.mode );
$b.printErrLine( 'modeForExtensionFrom: ' + argumentsObject.modeForExtensionFrom );
},
isThereAFlagInArguments: function( inString ) {
var normalizedEthalon = inString.toString().toLowerCase();
var objArgs = $thisArguments.getArgumentsObj();
var i;
var L = objArgs.length;
for ( i = 2; i < L; i++ ) {
var normalizedArgument = objArgs( i ).toString().toLowerCase();
if ( normalizedEthalon === normalizedArgument ) {
return true;
}
}
return false;
},
getArguments: {
folderFrom: function() {
var rR = '';
var objArgs = $thisArguments.getArgumentsObj();
if ( objArgs.length < 2 ) {
$b.printErrMessage(
' - reason: not enough arguments, ' +
'you MUST to provide at least 2 arguments, ' +
'but ammount of arguments you provided ' +
'is only: ' + objArgs.length
);
$b.die( basicOptions.errorCodes.badArguments );
}
rR = objArgs(0);
var fso = new ActiveXObject("Scripting.FileSystemObject");
rR = fso.GetAbsolutePathName( rR );
return rR;
},
folderTo: function() {
var rR = '';
var objArgs = $thisArguments.getArgumentsObj();
if ( objArgs.length < 2 ) {
$b.printErrMessage(
' - reason: not enough arguments, ' +
'you MUST to provide at least 2 arguments, ' +
'but ammount of arguments you provided ' +
'is only: ' + objArgs.length
);
$b.die( basicOptions.errorCodes.badArguments );
}
rR = objArgs(1);
var fso = new ActiveXObject("Scripting.FileSystemObject");
rR = fso.GetAbsolutePathName( rR );
return rR;
},
direction: function() {
var rR = 'from-id-1-to-id-2';
var hasFlag = $thisArguments.isThereAFlagInArguments;
if ( hasFlag( '/MapFrom2To1' ) ) {
rR = 'from-id-2-to-id-1';
}
return rR;
},
resultExtension: function() {
var rR = 'auto';
var hasFlag = $thisArguments.isThereAFlagInArguments;
if ( hasFlag( '/ResultExtension:none' ) ) {
rR = 'none';
}
if ( hasFlag( '/ResultExtension:21' ) ) {
rR = '21';
}
if ( hasFlag( '/ResultExtension:12' ) ) {
rR = '12';
}
if ( hasFlag( '/ResultExtension:2' ) ) {
rR = '2';
}
if ( hasFlag( '/ResultExtension:1' ) ) {
rR = '1';
}
return rR;
},
mode: function() {
var rR = 'training';
var hasFlag = $thisArguments.isThereAFlagInArguments;
if ( hasFlag( '/NotTraining' ) ) {
rR = 'not-training';
}
return rR;
},
modeForExtensionFrom: function() {
var rR = 'strict';
var hasFlag = $thisArguments.isThereAFlagInArguments;
if ( hasFlag( '/FuzzyExtensionsFrom' ) ) {
rR = 'fuzzy';
}
return rR;
}
},
getArgumentsAll: function() {
var $get = $thisArguments.getArguments;
var rR = {
folderFrom: $get.folderFrom(),
folderTo: $get.folderTo(),
direction: $get.direction(),
resultExtension: $get.resultExtension(),
mode: $get.mode(),
modeForExtensionFrom: $get.modeForExtensionFrom()
};
return rR;
}
};
var $a = $thisArguments;
//you can use it like this:
/*
var $inputOptions = $a.getArgumentsAll()
$a.print( $inputOptions );
*/
// $parser
// mockup options for separate testing
/*
var basicOptions = {
errorCodes: {
badParsing: 3
}
};
var $b = {
printErrMessage: function( a ) { console.log(a); },
die: function() { throw new Error(); }
};
*/
var $parser = {};
$parser.generateDummyLineReader = function( textBlock ) {
var lines = textBlock.split( '\r\n' );
var i = -1;
var L = lines.length;
var f = function() {
i++;
if ( i >= L ) {
return '';
}
return lines[i];
}
return f;
}
$parser.generateDummyInputOptions = function() {
return {
direction: '1-to-2',
resultExtension: '12',
folderFrom: 'C:\abc',
folderTo: 'D:\abc'
}
}
$parser.generateDummyMappingLineReader = function() {
return $parser.generateDummyLineReader(
[
'id:1',
'baseName:abcdef',
'extensionName:ext',
'id:2',
'baseName:input_001',
'extensionName:txt',
':',
'id:1',
'baseName:ghijkl',
'extensionName:jpg',
'id:2',
'baseName:input_002',
'extensionName:png',
':'
].join('\r\n')
);
}
/*
Remark:
functionReadNextLine
must be iterator that returns '' (aka empty string)
when stream of lines ends
functionForEachBlockDo must have
those arguments:
- id1Base
- id1Ext
- id2Base
- id2Ext
- $inputOptions
- functionCopyFile
$inputOptions must have properties
(wherever it mentioned in this block of comments):
- direction
- resultExtension
- folderFrom
- folderTo
functionCopyFile must have these arguments
- folderFrom
- fileFrom
- folderTo
- fileTo
*/
$parser.parseLinesAndForEachBlockDo = function(
functionReadNextLine,
functionForEachBlockDo,
$inputOptions,
functionCopyFile
) {
var buffer = null;
var nOfLine = 0;
var states = [
'waitingForId1',
'waitingForId2',
'waitingForBase',
'waitingForExtension',
'waitingForEndOfGroup'
];
function printErrorMessageAndDie( meaningfulPart ) {
$b.printErrMessage(
' - problem when parsing line ' + nOfLine + ': ' +
'[' + typeof line + ']' +
'"' + line + '"' +
meaningfulPart +
''
);
$b.die( basicOptions.errorCodes.badParsing );
}
var state = 'waitingForId1';
var line;
while (
( line = functionReadNextLine() ) !== ''
) {
++nOfLine;
var arOrNull = line.match( /^([a-zA-Z0-9-]*):(.*)$/ );
if (
( arOrNull === null )
) {
printErrorMessageAndDie(
'every line in mapping must be either' +
'"key:value" or ":"'
);
}
var key = arOrNull[1];
var value = arOrNull[2];
if (
( value.match( '\r' ) !== null )
) {
printErrorMessageAndDie(
'if line is ' +
'"key:value" ' +
'then it MUST NOT contain \r (CR) symbols ' +
'exept in terminator'
);
}
if ( state === 'waitingForId1' ) {
if (
( key === 'id' )
&&
( value === '1' )
) {
buffer = {};
buffer.nowGroup = {
id: 1
};
state = 'waitingForBase';
continue;
} else {
printErrorMessageAndDie(
'but this line must be "id:1"'
);
}
}
if ( state === 'waitingForBase' ) {
if (
( key === 'baseName' )
) {
buffer.nowGroup.base = value;
state = 'waitingForExtension';
continue;
} else {
printErrorMessageAndDie(
'but this line must be "baseName:...anything-here..."'
);
}
}
if ( state === 'waitingForExtension' ) {
if (
( key === 'extensionName' )
) {
buffer.nowGroup.ext = value;
if ( buffer.nowGroup.id === 1 ) {
state = 'waitingForId2';
} else {
state = 'waitingForEndOfGroup';
}
continue;
} else {
printErrorMessageAndDie(
'but this line must be "extensionName:...anything-here..."'
);
}
}
if ( state === 'waitingForId2' ) {
if (
( key === 'id' )
&&
( value === '2' )
) {
buffer.group1 = {
base: buffer.nowGroup.base,
ext: buffer.nowGroup.ext
}
buffer.nowGroup = {
id: 2
};
state = 'waitingForBase';
continue;
} else {
printErrorMessageAndDie(
'but this line must be "id:2"'
);
}
}
if ( state === 'waitingForEndOfGroup' ) {
if (
( key === '' )
&&
( value === '' )
) {
buffer.group2 = {
base: buffer.nowGroup.base,
ext: buffer.nowGroup.ext
}
functionForEachBlockDo(
buffer.group1.base,
buffer.group1.ext,
buffer.group2.base,
buffer.group2.ext,
$inputOptions,
functionCopyFile
);
buffer = null;
state = 'waitingForId1';
continue;
} else {
printErrorMessageAndDie(
'but this line must be ":"'
);
}
}
}
if ( buffer !== null ) {
printErrorMessageAndDie(
'dangling state (not all properties group are defined) - ' + state
);
}
}
/*
// test
// can be tested in for browser with only $parser object
$parser.parseLinesAndForEachBlockDo(
$parser.generateDummyMappingLineReader(),
function( a, b, c, d ) {
console.log( 'a:', a, 'b:', b, 'c:', c, 'd:', d );
}
);
*/
/*
Remark:
$inputOptions must have properties:
- direction
- resultExtension
- folderFrom
- folderTo
*/
$parser.reactionOnGoodParsedBlock = function(
id1Base, id1Ext,
id2Base, id2Ext,
$inputOptions,
functionCopyFile
) {
function glueExtensionToFileName(
fileName, extension
) {
fileName = fileName.toString();
extension = extension.toString();
if ( extension.length > 0 ) {
extension = '.' + extension;
}
return fileName + extension;
}
var folderFrom = $inputOptions.folderFrom;
var folderTo = $inputOptions.folderTo;
if ( $inputOptions.modeForExtensionFrom === 'fuzzy' ) {
var tmpFromBase = id1Base;
if ( $inputOptions.direction == 'from-id-2-to-id-1' ) {
tmpFromBase = id2Base;
}
var fuzzyFile = $fileListToolbox.getAnyFileWithBaseName(
tmpFromBase,
$fileListToolbox.getFileListForFolder( folderFrom )
);
if ( fuzzyFile !== false ) {
if ( $inputOptions.direction == 'from-id-2-to-id-1' ) {
id2Ext = fuzzyFile.fileNameExtension;
} else {
id1Ext = fuzzyFile.fileNameExtension;
}
}
}
var fromSet = { base: id1Base, ext: id1Ext };
var toSet = { base: id2Base, ext: id2Ext };
if ( $inputOptions.direction == 'from-id-2-to-id-1' ) {
fromSet = { base: id2Base, ext: id2Ext };
toSet = { base: id1Base, ext: id1Ext };
}
if ( $inputOptions.resultExtension === '21' ) {
toSet.ext = glueExtensionToFileName( id2Ext, id1Ext );
}
if ( $inputOptions.resultExtension === '12' ) {
toSet.ext = glueExtensionToFileName( id1Ext, id2Ext );
}
if ( $inputOptions.resultExtension === '2' ) {
toSet.ext = id2Ext;
}
if ( $inputOptions.resultExtension === '1' ) {
toSet.ext = id1Ext;
}
if ( $inputOptions.resultExtension === 'none' ) {
toSet.ext = '';
}
var fileFrom = glueExtensionToFileName( fromSet.base, fromSet.ext );
var fileTo = glueExtensionToFileName( toSet.base, toSet.ext );
functionCopyFile(
folderFrom, fileFrom,
folderTo, fileTo
);
}
/*
// test
// can be tested in for browser with only $parser object
$parser.reactionOnGoodParsedBlock(
'originalA', 'extA',
'originalB', 'extB',
{
direction: 'from-id-2-to-id-1',
resultExtension: 'auto',
folderFrom: 'C:\abc',
folderTo: 'D:\abc'
},
function(
folderFrom, fileFrom,
folderTo, fileTo
) {
console.log(
'folderFrom:', folderFrom,
'fileFrom:', fileFrom,
'folderTo:', folderTo,
'fileTo:', fileTo
);
}
);
// expected result:
// folderFrom: C:abc fileFrom: originalA.extA folderTo: D:abc fileTo: originalB.extB
*/
var $copyFileToolbox = {
copyFileTraining: function(
folderFrom, fileFrom,
folderTo, fileTo
) {
var fso = new ActiveXObject( "Scripting.FileSystemObject" );
if ( !fso.FolderExists( folderFrom ) ) {
$b.printErrWarning('folderFrom="' + folderFrom + '" doesn\'t exist');
}
if ( !fso.FolderExists( folderTo ) ) {
$b.printErrWarning('folderTo="' + folderTo + '" doesn\'t exist');
}
var pathFrom = fso.BuildPath( folderFrom, fileFrom );
var pathTo = fso.BuildPath( folderTo, fileTo );
if ( !fso.FileExists( pathFrom ) ) {
$b.printErrLine();
$b.printErrWarning('no source file found, script looking for it at pathFrom="' + pathFrom + '" - this file doesn\'t exist');
}
if ( fso.FileExists( pathTo ) ) {
$b.printErrLine();
$b.printErrWarning('be advised - there was found a file at destination for copy command, and in "NotTraining" mode you will overwrite file at pathTo="' + pathTo + '"');
}
$b.printLine( '' );
$b.printLine( 'Training mode: you ask to copy file' );
$b.printLine( 'from: ' + pathFrom );
$b.printLine( '\\/' );
$b.printLine( 'to: ' + pathTo );
},
copyFile: function(
folderFrom, fileFrom,
folderTo, fileTo
) {
var fso = new ActiveXObject( "Scripting.FileSystemObject" );
if ( !fso.FolderExists( folderFrom ) ) {
$b.printErrMessage(' folderFrom="' + folderFrom + '" doesn\'t exist');
$b.die( basicOptions.errorCodes.badCopy );
}
if ( !fso.FolderExists( folderTo ) ) {
$b.printErrMessage (' folderTo="' + folderTo + '" doesn\'t exist');
$b.die( basicOptions.errorCodes.badCopy );
}
var pathFrom = fso.BuildPath( folderFrom, fileFrom );
var pathTo = fso.BuildPath( folderTo, fileTo );
if ( !fso.FileExists( pathFrom ) ) {
$b.printErrMessage(' no source file found, script looking for it at pathFrom="' + pathFrom + '" doesn\'t exist');
$b.die( basicOptions.errorCodes.badCopy );
}
fso.copyFile( pathFrom, pathTo, true );
}
}
var $c = $copyFileToolbox;
// you can use it as:
/*
$c.copyFileTraining(
'./', '123.txt',
'b', '345.txt'
);
*/
// you will have a lot of problems testing if filename is unicode
// only way that I found for Windows 7 is to pass filename as stdin
// from some file (perhaps any streaming from file works ok here...)
// and yes, test shows that it works...
function main() {
var $inputOptions = $a.getArgumentsAll();
$b.printErrLine();
$b.printErrLine(
'Arguments for ' + basicOptions.scriptName +
' are interpreted this way:'
);
$a.print( $inputOptions );
$b.printErrLine();
var fCopyFile = $c.copyFileTraining;
if ( $inputOptions.mode === 'not-training' ) {
fCopyFile = $c.copyFile;
}
/*
var fuzzy = $fileListToolbox.getAnyFileWithBaseName(
'input_1',
$fileListToolbox.getFileListForFolder( 'bTmp' )
);
*/
$parser.parseLinesAndForEachBlockDo(
$s.getLine,
$parser.reactionOnGoodParsedBlock,
$inputOptions,
fCopyFile
);
$b.printErr( 'Script ' + basicOptions.scriptName + ' - finished!' );
};
main();

Create Order in prestashop programmatically

I am trying to create an order in prestashop programmatically,
Here are the steps I am following:
$billingAddress = $order->getBillingAddress();
$shippingAddress = $order->getShippingAddress();
if (empty($billingAddress)) {
continue;
}
$id_customer = $this->createPrestashopCustomer($billingAddress, $order->getEmail());
$lines = $order->getLines();
$AddressObject = new AddressCore();
$AddressObject->id_customer = $id_customer;
$AddressObject->firstname = $billingAddress->getfirstName();
$AddressObject->lastname = $billingAddress->getlastName();
$AddressObject->address1 = " " . $billingAddress->getHouseNr();
$AddressObject->address1.= " " . $billingAddress->getHouseNrAddition();
$AddressObject->address1.= " " . $billingAddress->getStreetName();
$AddressObject->address1.= " " . $billingAddress->getZipCode();
$AddressObject->address1.= " " . $billingAddress->getCity();
$AddressObject->city = $billingAddress->getCity();
$AddressObject->id_customer = $id_customer;
$AddressObject->id_country = CountryCore::getByIso($billingAddress->getCountryIso());
$AddressObject->alias = ($billingAddress->getcompanyName() != "") ? "Company" : "Home";
$AddressObject->add();
$currency_object = new CurrencyCore();
$default_currency_object = $currency_object->getDefaultCurrency();
$id_currency = $default_currency_object->id;
$id_address = $AddressObject->id;
$cart = new Cart();
$cart->id_customer = (int) $id_customer;
$cart->id_address_delivery = $id_address;
$cart->id_address_invoice = $id_address;
$cart->id_lang = 1;
$cart->id_currency = (int) $id_address;
$cart->id_carrier = 1;
$cart->recyclable = 0;
$cart->gift = 0;
$cart->add();
if (!empty($lines)) {
foreach ($lines as $item) {
$cart->updateQty(1, 5, 19);
}
}
$cart->update();
$order_object = new OrderCore();
$order_object->id_address_delivery = $id_address;
$order_object->id_address_invoice = $id_address;
$order_object->id_cart = $cart->id;
$order_object->id_currency = $id_currency;
$order_object->id_customer = $id_customer;
$CarrierObject = new CarrierCore();
$CarrierObject->delay[1] = "2-4";
$CarrierObject->active = 1;
$CarrierObject->name = "ChannelEngine Order2";
$CarrierObject->add();
$id_carrier = $CarrierObject->id;
$order_object->id_carrier = $id_carrier;
$order_object->payment = "Channel Engine Order";
$order_object->module = "1";
echo $order->getTotalInclVat();
$order_object->valid = 1;
$order_object->total_paid_tax_excl = $order->getTotalInclVat();
$order_object->total_discounts_tax_incl = $order->getTotalInclVat();
$order_object->total_paid = $order->getTotalInclVat();
$order_object->total_paid_real = $order->getTotalInclVat();
$order_object->total_products = $order->getSubTotalInclVat() - $order->getSubTotalVat();
$order_object->total_products_wt = $order->getSubTotalInclVat();
$order_object->conversion_rate = 1;
$order_object->id_shop = 1;
$order_object->id_lang = 1;
$order_object->secure_key = md5(uniqid(rand(), true));
$order_id = $order_object->add();
The Order is getting added to admin But somehow I can not see products in the order, Can anyone check and let me know what I am doing wrong here.
Also order total is also 0.
You should also create OrderDetail Objects for each product of this order.
Have a look at validateOrder() method of PaymentModule Class.
Here is an extract from this method:
$order = new Order();
$order->product_list = $package['product_list'];
if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_delivery') {
$address = new Address((int)$id_address);
$this->context->country = new Country((int)$address->id_country, (int)$this->context->cart->id_lang);
if (!$this->context->country->active) {
throw new PrestaShopException('The delivery address country is not active.');
}
}
$carrier = null;
if (!$this->context->cart->isVirtualCart() && isset($package['id_carrier'])) {
$carrier = new Carrier((int)$package['id_carrier'], (int)$this->context->cart->id_lang);
$order->id_carrier = (int)$carrier->id;
$id_carrier = (int)$carrier->id;
} else {
$order->id_carrier = 0;
$id_carrier = 0;
}
$order->id_customer = (int)$this->context->cart->id_customer;
$order->id_address_invoice = (int)$this->context->cart->id_address_invoice;
$order->id_address_delivery = (int)$id_address;
$order->id_currency = $this->context->currency->id;
$order->id_lang = (int)$this->context->cart->id_lang;
$order->id_cart = (int)$this->context->cart->id;
$order->reference = $reference;
$order->id_shop = (int)$this->context->shop->id;
$order->id_shop_group = (int)$this->context->shop->id_shop_group;
$order->secure_key = ($secure_key ? pSQL($secure_key) : pSQL($this->context->customer->secure_key));
$order->payment = $payment_method;
if (isset($this->name)) {
$order->module = $this->name;
}
$order->recyclable = $this->context->cart->recyclable;
$order->gift = (int)$this->context->cart->gift;
$order->gift_message = $this->context->cart->gift_message;
$order->mobile_theme = $this->context->cart->mobile_theme;
$order->conversion_rate = $this->context->currency->conversion_rate;
$amount_paid = !$dont_touch_amount ? Tools::ps_round((float)$amount_paid, 2) : $amount_paid;
$order->total_paid_real = 0;
$order->total_products = (float)$this->context->cart->getOrderTotal(false, Cart::ONLY_PRODUCTS, $order->product_list, $id_carrier);
$order->total_products_wt = (float)$this->context->cart->getOrderTotal(true, Cart::ONLY_PRODUCTS, $order->product_list, $id_carrier);
$order->total_discounts_tax_excl = (float)abs($this->context->cart->getOrderTotal(false, Cart::ONLY_DISCOUNTS, $order->product_list, $id_carrier));
$order->total_discounts_tax_incl = (float)abs($this->context->cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS, $order->product_list, $id_carrier));
$order->total_discounts = $order->total_discounts_tax_incl;
$order->total_shipping_tax_excl = (float)$this->context->cart->getPackageShippingCost((int)$id_carrier, false, null, $order->product_list);
$order->total_shipping_tax_incl = (float)$this->context->cart->getPackageShippingCost((int)$id_carrier, true, null, $order->product_list);
$order->total_shipping = $order->total_shipping_tax_incl;
if (!is_null($carrier) && Validate::isLoadedObject($carrier)) {
$order->carrier_tax_rate = $carrier->getTaxesRate(new Address((int)$this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
}
$order->total_wrapping_tax_excl = (float)abs($this->context->cart->getOrderTotal(false, Cart::ONLY_WRAPPING, $order->product_list, $id_carrier));
$order->total_wrapping_tax_incl = (float)abs($this->context->cart->getOrderTotal(true, Cart::ONLY_WRAPPING, $order->product_list, $id_carrier));
$order->total_wrapping = $order->total_wrapping_tax_incl;
$order->total_paid_tax_excl = (float)Tools::ps_round((float)$this->context->cart->getOrderTotal(false, Cart::BOTH, $order->product_list, $id_carrier), _PS_PRICE_COMPUTE_PRECISION_);
$order->total_paid_tax_incl = (float)Tools::ps_round((float)$this->context->cart->getOrderTotal(true, Cart::BOTH, $order->product_list, $id_carrier), _PS_PRICE_COMPUTE_PRECISION_);
$order->total_paid = $order->total_paid_tax_incl;
$order->round_mode = Configuration::get('PS_PRICE_ROUND_MODE');
$order->round_type = Configuration::get('PS_ROUND_TYPE');
$order->invoice_date = '0000-00-00 00:00:00';
$order->delivery_date = '0000-00-00 00:00:00';
if (self::DEBUG_MODE) {
PrestaShopLogger::addLog('PaymentModule::validateOrder - Order is about to be added', 1, null, 'Cart', (int)$id_cart, true);
}
// Creating order
$result = $order->add();
if (!$result) {
PrestaShopLogger::addLog('PaymentModule::validateOrder - Order cannot be created', 3, null, 'Cart', (int)$id_cart, true);
throw new PrestaShopException('Can\'t save Order');
}
// Amount paid by customer is not the right one -> Status = payment error
// We don't use the following condition to avoid the float precision issues : http://www.php.net/manual/en/language.types.float.php
// if ($order->total_paid != $order->total_paid_real)
// We use number_format in order to compare two string
if ($order_status->logable && number_format($cart_total_paid, _PS_PRICE_COMPUTE_PRECISION_) != number_format($amount_paid, _PS_PRICE_COMPUTE_PRECISION_)) {
$id_order_state = Configuration::get('PS_OS_ERROR');
}
$order_list[] = $order;
if (self::DEBUG_MODE) {
PrestaShopLogger::addLog('PaymentModule::validateOrder - OrderDetail is about to be added', 1, null, 'Cart', (int)$id_cart, true);
}
// Insert new Order detail list using cart for the current order
$order_detail = new OrderDetail(null, null, $this->context);
$order_detail->createList($order, $this->context->cart, $id_order_state, $order->product_list, 0, true, $package_list[$id_address][$id_package]['id_warehouse']);
$order_detail_list[] = $order_detail;
if (self::DEBUG_MODE) {
PrestaShopLogger::addLog('PaymentModule::validateOrder - OrderCarrier is about to be added', 1, null, 'Cart', (int)$id_cart, true);
}
// Adding an entry in order_carrier table
if (!is_null($carrier)) {
$order_carrier = new OrderCarrier();
$order_carrier->id_order = (int)$order->id;
$order_carrier->id_carrier = (int)$id_carrier;
$order_carrier->weight = (float)$order->getTotalWeight();
$order_carrier->shipping_cost_tax_excl = (float)$order->total_shipping_tax_excl;
$order_carrier->shipping_cost_tax_incl = (float)$order->total_shipping_tax_incl;
$order_carrier->add();
}
Create Order Programatically in prestashop, we need to use validate order function to create order manually in prestashop.
<?php
$cart = new Cart(Context::getContext()->cart);
$summary = $cart->getSummaryDetails($id_lang,true);
$total = (string) $summary['total_price'];
$cashondelivery = new CashOnDelivery();
if($cashondelivery->validateOrder((int) $cart->id,2, $total, $cashondelivery->displayName, null, array(),$id_currency, false, false)) {
$result['orderid']=(string)$cashondelivery->currentOrder;
return $result;
}