This file is the database ID information all the fields and went and came to a Blade, I want to an ID information entered in the same panel Blade I send my face.
class DataGrid extends DataSet
{
protected $fields = array();
/** #var Column[] */
public $columns = array();
public $headers = array();
public $rows = array();
public $output = "";
public $attributes = array("class" => "table");
public $checkbox_form = false;
protected $row_callable = array();
/**
* #param string $name
* #param string $label
* #param bool $orderby
*
* #return Column
*/
public function add($name, $label = null, $orderby = false)
{
$column = new Column($name, $label, $orderby);
$this->columns[$column->name] = $column;
if (!in_array($name,array("_edit"))) {
$this->headers[] = $label;
}
if ($orderby) {
$this->addOrderBy($column->orderby_field);
}
return $column;
}
//todo: like "field" for DataForm, should be nice to work with "cell" as instance and "row" as collection of cells
public function build($view = '')
{
($view == '') and $view = 'rapyd::datagrid';
parent::build();
Persistence::save();
foreach ($this->data as $tablerow) {
$row = new Row($tablerow);
foreach ($this->columns as $column) {
$cell = new Cell($column->name);
$sanitize = (count($column->filters) || $column->cell_callable) ? false : true;
$value = $this->getCellValue($column, $tablerow, $sanitize);
$cell->value($value);
$cell->parseFilters($column->filters);
if ($column->cell_callable) {
$callable = $column->cell_callable;
$cell->value($callable($cell->value, $tablerow));
}
$row->add($cell);
}
if (count($this->row_callable)) {
foreach ($this->row_callable as $callable) {
$callable($row);
}
}
$this->rows[] = $row;
}
$routeParamters = \Route::current()->parameters();
return \View::make($view, array('dg' => $this, 'buttons'=>$this->button_container, 'label'=>$this->label,
'current_entity' => $routeParamters['entity']));
}
public function buildCSV($file = '', $timestamp = '', $sanitize = true,$del = array())
{
$this->limit = null;
parent::build();
$segments = \Request::segments();
$filename = ($file != '') ? basename($file, '.csv') : end($segments);
$filename = preg_replace('/[^0-9a-z\._-]/i', '',$filename);
$filename .= ($timestamp != "") ? date($timestamp).".csv" : ".csv";
$save = (bool) strpos($file,"/");
//Delimiter
$delimiter = array();
$delimiter['delimiter'] = isset($del['delimiter']) ? $del['delimiter'] : ';';
$delimiter['enclosure'] = isset($del['enclosure']) ? $del['enclosure'] : '"';
$delimiter['line_ending'] = isset($del['line_ending']) ? $del['line_ending'] : "\n";
if ($save) {
$handle = fopen(public_path().'/'.dirname($file)."/".$filename, 'w');
} else {
$headers = array(
'Content-Type' => 'text/csv',
'Pragma'=>'no-cache',
'"Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
'Content-Disposition' => 'attachment; filename="' . $filename.'"');
$handle = fopen('php://output', 'w');
ob_start();
}
fputs($handle, $delimiter['enclosure'].implode($delimiter['enclosure'].$delimiter['delimiter'].$delimiter['enclosure'], $this->headers) .$delimiter['enclosure'].$delimiter['line_ending']);
foreach ($this->data as $tablerow) {
$row = new Row($tablerow);
foreach ($this->columns as $column) {
if (in_array($column->name,array("_edit")))
continue;
$cell = new Cell($column->name);
$value = str_replace('"', '""',str_replace(PHP_EOL, '', strip_tags($this->getCellValue($column, $tablerow, $sanitize))));
$cell->value($value);
$row->add($cell);
}
if (count($this->row_callable)) {
foreach ($this->row_callable as $callable) {
$callable($row);
}
}
fputs($handle, $delimiter['enclosure'] . implode($delimiter['enclosure'].$delimiter['delimiter'].$delimiter['enclosure'], $row->toArray()) . $delimiter['enclosure'].$delimiter['line_ending']);
}
fclose($handle);
if ($save) {
//redirect, boolean or filename?
} else {
$output = ob_get_clean();
return \Response::make(rtrim($output, "\n"), 200, $headers);
}
}
protected function getCellValue($column, $tablerow, $sanitize = true)
{
//blade
if (strpos($column->name, '{{') !== false ||
strpos($column->name, '{!!') !== false) {
if (is_object($tablerow) && method_exists($tablerow, "getAttributes")) {
$fields = $tablerow->getAttributes();
$relations = $tablerow->getRelations();
$array = array_merge($fields, $relations) ;
$array['row'] = $tablerow;
} else {
$array = (array) $tablerow;
}
$value = $this->parser->compileString($column->name, $array);
//eager loading smart syntax relation.field
} elseif (preg_match('#^[a-z0-9_-]+(?:\.[a-z0-9_-]+)+$#i',$column->name, $matches) && is_object($tablerow) ) {
//switch to blade and god bless eloquent
$_relation = '$'.trim(str_replace('.','->', $column->name));
$expression = '{{ isset('. $_relation .') ? ' . $_relation . ' : "" }}';
$fields = $tablerow->getAttributes();
$relations = $tablerow->getRelations();
$array = array_merge($fields, $relations) ;
$value = $this->parser->compileString($expression, $array);
//fieldname in a collection
} elseif (is_object($tablerow)) {
$value = #$tablerow->{$column->name};
if ($sanitize) {
$value = $this->sanitize($value);
}
//fieldname in an array
} elseif (is_array($tablerow) && isset($tablerow[$column->name])) {
$value = $tablerow[$column->name];
//none found, cell will have the column name
} else {
$value = $column->name;
}
//decorators, should be moved in another method
if ($column->link) {
if (is_object($tablerow) && method_exists($tablerow, "getAttributes")) {
$array = $tablerow->getAttributes();
$array['row'] = $tablerow;
} else {
$array = (array) $tablerow;
}
$value = ''.$value.'';
}
if (count($column->actions)>0) {
$key = ($column->key != '') ? $column->key : $this->key;
$keyvalue = #$tablerow->{$key};
$routeParamters = \Route::current()->parameters();
$value = \View::make('rapyd::datagrid.actions', array('uri' => $column->uri, 'id' => $keyvalue, 'actions' => $column->actions,
'current_entity' => $routeParamters['entity']));
}
return $value;
}
public function getGrid($view = '')
{
$this->output = $this->build($view)->render();
return $this->output;
}
public function __toString()
{
if ($this->output == "") {
//to avoid the error "toString() must not throw an exception"
//http://stackoverflow.com/questions/2429642/why-its-impossible-to-throw-exception-from-tostring/27307132#27307132
try {
$this->getGrid();
}
catch (\Exception $e) {
$previousHandler = set_exception_handler(function (){ });
restore_error_handler();
call_user_func($previousHandler, $e);
die;
}
}
return $this->output;
}
public function edit($uri, $label='Edit', $actions='show|modify|delete', $key = '')
{
return $this->add('_edit', $label)->actions($uri, explode('|', $actions))->key($key);
}
public function getColumn($column_name)
{
if (isset($this->columns[$column_name])) {
return $this->columns[$column_name];
}
}
public function addActions($uri, $label='Edit', $actions='show|modify|delete', $key = '')
{
return $this->edit($uri, $label, $actions, $key);
}
public function row(\Closure $callable)
{
$this->row_callable[] = $callable;
return $this;
}
protected function sanitize($string)
{
$result = nl2br(htmlspecialchars($string));
return Config::get('rapyd.sanitize.num_characters') > 0 ? str_limit($result, Config::get('rapyd.sanitize.num_characters')) : $result;
}
public function rowCount()
{
return count($this->rows);
}
}
This is the source of a rapyd-laravel widget/package, not a custom code.
According to DataGrid/DataSet documentation, you can use many sources:
https://github.com/zofe/rapyd-laravel/wiki/DataSet
DataSet/DataGrid are presenters, you can retrieve all data of your data source using
{{ $item->field }} or {{ $row->field }} respectively
See the docs please
https://github.com/zofe/rapyd-laravel/wiki
Related
i have Product Model and it have bread in voyager and everything is ok.
Products have publisher_id column if null == main else int(id of publisher).
i want create multiple browse blade but one of those is default voyager blade
and another where('publisher_id','!=',null)
to show .
how to created it with route ?
thanks .
fixed with resource route
Route::resource('products/index/publisher', VoyagerProductPublisherController::class);
Route::resource('products/index/notaccept', VoyagerProductPublisherNotAcceptController::class);
and then in controllers index function write query
public function index(Request $request)
{
// GET THE SLUG, ex. 'posts', 'pages', etc.
$slug = \request()->segment(3);
// GET THE DataType based on the slug
$dataType = Voyager::model('DataType')->where('slug', '=', $slug)->first();
// Check permission
$getter = 'paginate';
$search = (object)['value' => $request->get('s'), 'key' => $request->get('key'), 'filter' => $request->get('filter')];
$searchNames = [];
if ($dataType->server_side) {
$searchNames = $dataType->browseRows->mapWithKeys(function ($row) {
return [$row['field'] => $row->getTranslatedAttribute('display_name')];
});
}
$orderBy = $request->get('order_by', $dataType->order_column);
$sortOrder = $request->get('sort_order', $dataType->order_direction);
$usesSoftDeletes = false;
$showSoftDeleted = false;
// Next Get or Paginate the actual content from the MODEL that corresponds to the slug DataType
if (strlen($dataType->model_name) != 0) {
$model = app($dataType->model_name);
$query = $model::select($dataType->name . '.*');
if ($dataType->scope && $dataType->scope != '' && method_exists($model, 'scope' . ucfirst($dataType->scope))) {
$query->{$dataType->scope}();
}
// Use withTrashed() if model uses SoftDeletes and if toggle is selected
if ($model && in_array(SoftDeletes::class, class_uses_recursive($model))) {
$usesSoftDeletes = true;
if ($request->showSoftDeleted && $request->showSoftDeleted == 1) {
$showSoftDeleted = true;
$query = $query->onlyTrashed();
}
}
// If a column has a relationship associated with it, we do not want to show that field
$this->removeRelationshipField($dataType, 'browse');
if ($search->value != '' && $search->key && $search->filter) {
$search_filter = ($search->filter == 'equals') ? '=' : 'LIKE';
$search_value = ($search->filter == 'equals') ? $search->value : '%' . $search->value . '%';
$searchField = $dataType->name . '.' . $search->key;
if ($row = $this->findSearchableRelationshipRow($dataType->rows->where('type', 'relationship'), $search->key)) {
$query->whereIn(
$searchField,
$row->details->model::where($row->details->label, $search_filter, $search_value)->pluck('id')->toArray()
);
} else {
if ($dataType->browseRows->pluck('field')->contains($search->key)) {
$query->where($searchField, $search_filter, $search_value);
}
}
}
$row = $dataType->rows->where('field', $orderBy)->firstWhere('type', 'relationship');
if ($orderBy && (in_array($orderBy, $dataType->fields()) || !empty($row))) {
$querySortOrder = (!empty($sortOrder)) ? $sortOrder : 'desc';
if (!empty($row)) {
$query->select([
$dataType->name . '.*',
'joined.' . $row->details->label . ' as ' . $orderBy,
])->leftJoin(
$row->details->table . ' as joined',
$dataType->name . '.' . $row->details->column,
'joined.' . $row->details->key,
);
}
$dataTypeContent = call_user_func([
$query->orderBy($orderBy, $querySortOrder)->where('publisher_id','!=',null),
$getter,
]);
} elseif ($model->timestamps) {
$dataTypeContent = call_user_func([$query->latest($model::CREATED_AT)->where('publisher_id','!=',null), 'paginate'], request()->perPage ?? 10);
} else {
$dataTypeContent = call_user_func([$query->orderBy($model->getKeyName(), 'DESC')->where('publisher_id','!=',null), $getter]);
}
// Replace relationships' keys for labels and create READ links if a slug is provided.
$dataTypeContent = $this->resolveRelations($dataTypeContent, $dataType);
} else {
// If Model doesn't exist, get data from table name
$dataTypeContent = call_user_func([DB::table($dataType->name)->where('publisher_id','!=',null), $getter]);
$model = false;
}
// Check if BREAD is Translatable
$isModelTranslatable = is_bread_translatable($model);
// Eagerload Relations
$this->eagerLoadRelations($dataTypeContent, $dataType, 'browse', $isModelTranslatable);
// Check if server side pagination is enabled
$isServerSide = isset($dataType->server_side) && $dataType->server_side;
// Check if a default search key is set
$defaultSearchKey = $dataType->default_search_key ?? null;
// Actions
$actions = [];
if (!empty($dataTypeContent->first())) {
foreach (Voyager::actions() as $action) {
$action = new $action($dataType, $dataTypeContent->first());
if ($action->shouldActionDisplayOnDataType()) {
$actions[] = $action;
}
}
}
//Define showCheckboxColumn
$showCheckboxColumn = false;
if (Auth::guard('admin')->user()->can('delete', app($dataType->model_name))) {
$showCheckboxColumn = true;
} else {
foreach ($actions as $action) {
if (method_exists($action, 'massAction')) {
$showCheckboxColumn = true;
}
}
}
// Define orderColumn
$orderColumn = [];
if ($orderBy) {
$index = $dataType->browseRows->where('field', $orderBy)->keys()->first() + ($showCheckboxColumn ? 1 : 0);
$orderColumn = [[$index, $sortOrder ?? 'desc']];
}
// Define list of columns that can be sorted server side
$sortableColumns = $this->getSortableColumns($dataType->browseRows);
$view = 'voyager::bread.publisher';
if (view()->exists("voyager::$slug.publisher")) {
$view = "voyager::$slug.publisher";
}
return Voyager::view($view, compact(
'actions',
'dataType',
'dataTypeContent',
'isModelTranslatable',
'search',
'orderBy',
'orderColumn',
'sortableColumns',
'sortOrder',
'searchNames',
'isServerSide',
'defaultSearchKey',
'usesSoftDeletes',
'showSoftDeleted',
'showCheckboxColumn'
));
}
// in controller two
public function index(Request $request)
{
// GET THE SLUG, ex. 'posts', 'pages', etc.
$slug = \request()->segment(3);
// GET THE DataType based on the slug
$dataType = Voyager::model('DataType')->where('slug', '=', $slug)->first();
// Check permission
$getter = 'paginate';
$search = (object)['value' => $request->get('s'), 'key' => $request->get('key'), 'filter' => $request->get('filter')];
$searchNames = [];
if ($dataType->server_side) {
$searchNames = $dataType->browseRows->mapWithKeys(function ($row) {
return [$row['field'] => $row->getTranslatedAttribute('display_name')];
});
}
$orderBy = $request->get('order_by', $dataType->order_column);
$sortOrder = $request->get('sort_order', $dataType->order_direction);
$usesSoftDeletes = false;
$showSoftDeleted = false;
// Next Get or Paginate the actual content from the MODEL that corresponds to the slug DataType
if (strlen($dataType->model_name) != 0) {
$model = app($dataType->model_name);
$query = $model::select($dataType->name . '.*');
if ($dataType->scope && $dataType->scope != '' && method_exists($model, 'scope' . ucfirst($dataType->scope))) {
$query->{$dataType->scope}();
}
// Use withTrashed() if model uses SoftDeletes and if toggle is selected
if ($model && in_array(SoftDeletes::class, class_uses_recursive($model))) {
$usesSoftDeletes = true;
if ($request->showSoftDeleted && $request->showSoftDeleted == 1) {
$showSoftDeleted = true;
$query = $query->onlyTrashed();
}
}
// If a column has a relationship associated with it, we do not want to show that field
$this->removeRelationshipField($dataType, 'browse');
if ($search->value != '' && $search->key && $search->filter) {
$search_filter = ($search->filter == 'equals') ? '=' : 'LIKE';
$search_value = ($search->filter == 'equals') ? $search->value : '%' . $search->value . '%';
$searchField = $dataType->name . '.' . $search->key;
if ($row = $this->findSearchableRelationshipRow($dataType->rows->where('type', 'relationship'), $search->key)) {
$query->whereIn(
$searchField,
$row->details->model::where($row->details->label, $search_filter, $search_value)->pluck('id')->toArray()
);
} else {
if ($dataType->browseRows->pluck('field')->contains($search->key)) {
$query->where($searchField, $search_filter, $search_value);
}
}
}
$row = $dataType->rows->where('field', $orderBy)->firstWhere('type', 'relationship');
if ($orderBy && (in_array($orderBy, $dataType->fields()) || !empty($row))) {
$querySortOrder = (!empty($sortOrder)) ? $sortOrder : 'desc';
if (!empty($row)) {
$query->select([
$dataType->name . '.*',
'joined.' . $row->details->label . ' as ' . $orderBy,
])->leftJoin(
$row->details->table . ' as joined',
$dataType->name . '.' . $row->details->column,
'joined.' . $row->details->key,
);
}
$dataTypeContent = call_user_func([
$query->orderBy($orderBy, $querySortOrder)->where('accept',0),
$getter,
]);
} elseif ($model->timestamps) {
$dataTypeContent = call_user_func([$query->latest($model::CREATED_AT)->where('accept',0), 'paginate'], request()->perPage ?? 10);
} else {
$dataTypeContent = call_user_func([$query->orderBy($model->getKeyName(), 'DESC')->where('accept',0), $getter]);
}
// Replace relationships' keys for labels and create READ links if a slug is provided.
$dataTypeContent = $this->resolveRelations($dataTypeContent, $dataType);
} else {
// If Model doesn't exist, get data from table name
$dataTypeContent = call_user_func([DB::table($dataType->name)->where('accept',0), $getter]);
$model = false;
}
// Check if BREAD is Translatable
$isModelTranslatable = is_bread_translatable($model);
// Eagerload Relations
$this->eagerLoadRelations($dataTypeContent, $dataType, 'browse', $isModelTranslatable);
// Check if server side pagination is enabled
$isServerSide = isset($dataType->server_side) && $dataType->server_side;
// Check if a default search key is set
$defaultSearchKey = $dataType->default_search_key ?? null;
// Actions
$actions = [];
if (!empty($dataTypeContent->first())) {
foreach (Voyager::actions() as $action) {
$action = new $action($dataType, $dataTypeContent->first());
if ($action->shouldActionDisplayOnDataType()) {
$actions[] = $action;
}
}
}
//Define showCheckboxColumn
$showCheckboxColumn = false;
if (Auth::guard('admin')->user()->can('delete', app($dataType->model_name))) {
$showCheckboxColumn = true;
} else {
foreach ($actions as $action) {
if (method_exists($action, 'massAction')) {
$showCheckboxColumn = true;
}
}
}
// Define orderColumn
$orderColumn = [];
if ($orderBy) {
$index = $dataType->browseRows->where('field', $orderBy)->keys()->first() + ($showCheckboxColumn ? 1 : 0);
$orderColumn = [[$index, $sortOrder ?? 'desc']];
}
// Define list of columns that can be sorted server side
$sortableColumns = $this->getSortableColumns($dataType->browseRows);
$view = 'voyager::bread.notaccept';
if (view()->exists("voyager::$slug.notaccept")) {
$view = "voyager::$slug.notaccept";
}
return Voyager::view($view, compact(
'actions',
'dataType',
'dataTypeContent',
'isModelTranslatable',
'search',
'orderBy',
'orderColumn',
'sortableColumns',
'sortOrder',
'searchNames',
'isServerSide',
'defaultSearchKey',
'usesSoftDeletes',
'showSoftDeleted',
'showCheckboxColumn'
));
}
thanks for view .
I'm on Prestashop 1.7.6. I made a simple test module for adding a custom carrier and manage it programmatically.
Everything works well during checkout: I see new carrier with the correct cost, if I select it the total of cart is correct! (the shipping cost is added).
After choosing the payment method and confirming the order (and I'm redirected to order confirmation page), the shipping costs disappear: is always free shipping!
I do not understand why..
I report the code of this test:
<?php
if (!defined('_PS_VERSION_')) {
exit;
}
class TxShipping extends CarrierModule
{
const PREFIX = 'tx_';
public $id_carrier;
private $loopCount = 0;
private $shipCost = 0;
protected $_hooks = array(
'actionCarrierUpdate',
'displayOrderConfirmation',
);
protected $_carriers = array(
//"Public carrier name" => "technical name",
'My new carrier' => 'txshipping',
);
public function __construct()
{
$this->name = 'txshipping';
$this->tab = 'shipping_logistics';
$this->version = '1.0.0';
$this->author = 'Gerry';
$this->need_instance = 0;
$this->ps_versions_compliancy = [
'min' => '1.7.1.0',
'max' => _PS_VERSION_
];
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Tx Shipping');
$this->description = $this->l('manage shipping costs');
$this->confirmUninstall = $this->l('Are you sure you want to uninstall?');
if (!Configuration::get('TXSHIPPING_NAME')) {
$this->warning = $this->l('No name provided');
}
}
public function getTemplate($area, $file)
{
return 'views/templates/' . $area . '/' . $file;
}
//-------------------------------------------------
// Hooks
//-------------------------------------------------
public function hookActionCarrierUpdate($params)
{
if ($params['carrier']->id_reference == Configuration::get(self::PREFIX . 'fcd_reference')) {
Configuration::updateValue(self::PREFIX . 'fcd', $params['carrier']->id);
}
}
public function getOrderShippingCost($params = null, $shipping_cost = 0) {
$curPage = $this->context->controller->php_self;
/* using test on which page is running cause the following code is always executed (even if is loading home page!?)
I don't understand why */
if ($curPage == "order") {
$this->loopCount++; // attempt for not to run the same code over and over.. but it doesn't work very well
if ($this->loopCount == 1) {
$this->shipCost = 77;
/*
$address = new Address($params->id_address_delivery);
$cap = $address->postcode;
$curID = $this->id_carrier; */
}
return floatval($this->shipCost);
} elseif ($curPage == "order-confirmation") {
$test = 76; // for simple test
return floatval($test);
} else {
if ($curPage != "pagenotfound") {
$this->loopCount = 0;
$this->shipCost = 0;
}
}
}
public function getOrderShippingCostExternal($params){
//return 999; costi spedizione
return $this->getOrderShippingCost($params, 0);
}
//-------------------------------------------------
// Setup
//-------------------------------------------------
public function install()
{
if (parent::install()) {
foreach ($this->_hooks as $hook) {
if (!$this->registerHook($hook)) {
return false;
}
}
if (!$this->createCarriers()) {
return false;
}
return true;
}
return false;
}
public function uninstall()
{
if (parent::uninstall()) {
foreach ($this->_hooks as $hook) {
if (!$this->unregisterHook($hook)) {
return false;
}
}
if (!$this->deleteCarriers()) {
return false;
}
return true;
}
return false;
}
//-------------------------------------------------
// Funzioni private
//-------------------------------------------------
protected function createCarriers()
{
foreach ($this->_carriers as $key => $value) {
//Create own carrier
$carrier = new Carrier();
$carrier->name = $key;
$carrier->id_tax_rules_group = 0;
$carrier->active = 1;
$carrier->deleted = 0;
foreach (Language::getLanguages(true) as $language)
$carrier->delay[(int)$language['id_lang']] = 'Delay [1-2 days]';
$carrier->shipping_handling = false;
$carrier->range_behavior = 0;
$carrier->is_module = true;
$carrier->shipping_external = true;
$carrier->external_module_name = $this->name;
$carrier->need_range = true;
if ($carrier->add()) {
$groups = Group::getGroups(true);
foreach ($groups as $group) {
Db::getInstance()->autoExecute(_DB_PREFIX_ . 'carrier_group', array(
'id_carrier' => (int) $carrier->id,
'id_group' => (int) $group['id_group']
), 'INSERT');
}
$rangePrice = new RangePrice();
$rangePrice->id_carrier = $carrier->id;
$rangePrice->delimiter1 = '0';
$rangePrice->delimiter2 = '1000000';
$rangePrice->add();
$rangeWeight = new RangeWeight();
$rangeWeight->id_carrier = $carrier->id;
$rangeWeight->delimiter1 = '0';
$rangeWeight->delimiter2 = '1000000';
$rangeWeight->add();
$zones = Zone::getZones(true);
foreach ($zones as $z) {
Db::getInstance()->autoExecute(_DB_PREFIX_ . 'carrier_zone',
array('id_carrier' => (int) $carrier->id, 'id_zone' => (int) $z['id_zone']), 'INSERT');
Db::getInstance()->autoExecuteWithNullValues(_DB_PREFIX_ . 'delivery',
array('id_carrier' => $carrier->id, 'id_range_price' => (int) $rangePrice->id, 'id_range_weight' => NULL, 'id_zone' => (int) $z['id_zone'], 'price' => '0'), 'INSERT');
Db::getInstance()->autoExecuteWithNullValues(_DB_PREFIX_ . 'delivery',
array('id_carrier' => $carrier->id, 'id_range_price' => NULL, 'id_range_weight' => (int) $rangeWeight->id, 'id_zone' => (int) $z['id_zone'], 'price' => '0'), 'INSERT');
}
copy(dirname(__FILE__) . '/views/img/carrier.jpg', _PS_SHIP_IMG_DIR_ . '/' . (int) $carrier->id . '.jpg');
Configuration::updateValue(self::PREFIX . $value, $carrier->id);
Configuration::updateValue(self::PREFIX . $value . '_reference', $carrier->id);
}
}
return true;
}
protected function deleteCarriers()
{
foreach ($this->_carriers as $value) {
$tmp_carrier_id = Configuration::get(self::PREFIX . $value);
$carrier = new Carrier($tmp_carrier_id);
$carrier->delete();
}
return true;
}
}
Im my opinion it has something to do with your $curPage
I'd go for this if instead:
if ($this->context->controller instanceof CartController || $this->context->controller instanceof OrderController) {
I don't understand this part of code:
} elseif ($curPage == "order-confirmation") {
why would you do something different on real order-confirmation page where order is already placed?
On my multiple upload library I have a function which is called upload data.
And another function called upload.
For some reason when I select multiple images and is success full when I use on my controller
$data = $this->multiple_upload->upload_data();
echo $data['file_name'];
It will only get the name of the last file selected it does not return all file names selected. It should display all file names selected.
Question: How on my library function upload_data() can I make sure can return data correctly rather than just the last one. the upload_data function just seems to only return the last file information.
Library
<?php
class Multiple_upload {
public function __construct($config = array()) {
$this->CI =& get_instance();
$this->files = $this->clean($_FILES);
empty($config) OR $this->set_config($config);
}
public function set_config($config) {
foreach ($config as $key => $value) {
$this->$key = $value;
}
return $this;
}
public function upload($field = 'userfile') {
if (empty($this->upload_path)) {
$this->set_error('upload_path_not_set');
return FALSE;
}
if (!realpath(FCPATH . $this->upload_path)) {
$this->set_error('upload_path_in_correct');
return FALSE;
}
if (!empty($this->files[$field]['name'][0])) {
$check_error = 0;
foreach ($this->files[$field]['name'] as $key => $value) {
$this->file_name = $this->files[$field]['name'][$key];
$this->file_temp = $this->files[$field]['tmp_name'][$key];
$this->file_size = $this->files[$field]['size'][$key];
$this->get_file_extension = explode('.', $this->files[$field]['name'][$key]);
$this->get_file_extension_end = strtolower(end($this->get_file_extension));
if (!in_array($this->get_file_extension_end, $this->allowed_types)) {
$this->set_error('file_extension_not_allowed');
$check_error++;
}
if ($this->files[$field]['size'][$key] > $this->max_size) {
$this->set_error('file_size_check');
$check_error++;
}
if ( ! #copy($this->file_temp, FCPATH . $this->upload_path . '/' . $this->file_name)) {
if ( ! #move_uploaded_file($this->file_temp, FCPATH . $this->upload_path . '/' . $this->file_name)) {
$this->set_error('upload_destination_error', 'error');
$check_error++;
}
}
}
if($check_error > 0 ) {
return FALSE;
}
// This lets me get file data in another function
return $this;
}
}
public function upload_data() {
$data = array(
'file_name' => $this->file_name,
'file_path' => FCPATH . $this->upload_path . '/'
);
return $data;
}
public function set_error($message) {
$this->CI->lang->load('upload', 'english');
$msg = "";
if ($message == 'upload_path_not_set') {
$msg .= $this->CI->lang->line($message);
}
if ($message == 'upload_path_in_correct') {
$msg .= $this->CI->lang->line($message);
}
if ($message == 'file_extension_not_allowed') {
$msg .= sprintf($this->CI->lang->line($message), $this->file_name, $this->get_file_extension_end);
}
if ($message == 'file_size_check') {
$msg .= sprintf($this->CI->lang->line($message), $this->file_name, $this->max_size);
}
return $this->error_message[] = $msg;
}
public function display_error_messages($open_tag = '<p>', $close_tag = '</p>') {
$message = "";
if (isset($this->error_message)) {
foreach($this->error_message as $msg) {
$message .= $open_tag . $msg . $close_tag;
}
}
return $message;
}
public function clean($data) {
if (is_array($data)) {
foreach ($data as $key => $value) {
unset($data[$key]);
$data[$this->clean($key)] = $this->clean($value);
}
} else {
$data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
}
return $data;
}
}
I have tried
public function upload_data() {
$data[] = array(
'file_name' => $this->file_name,
'file_path' => FCPATH . $this->upload_path . '/'
);
return $data;
}
Controller index function
public function index(){
$data['error'] = '';
$this->load->library('multiple_upload');
$config['upload_path'] = 'uploads';
$config['allowed_types'] = array('jpg', 'png');
$config['max_size'] = 3000000;
//$config['max_size'] = 1000;
$config['overwrite'] = TRUE;
$this->multiple_upload->set_config($config);
if ($this->multiple_upload->upload() == FALSE) {
$data['error'] = $this->multiple_upload->display_error_messages('<div class="alert alert-danger">', '</div>');
$this->load->view('upload', $data);
} else {
$data = $this->multiple_upload->upload_data();
echo $data['file_name'];
}
}
<?php
class Multiple_upload {
private $filenames;
public function __construct($config = array()) {
$this->CI =& get_instance();
$this->files = $this->clean($_FILES);
$this->filenames = array();
empty($config) OR $this->set_config($config);
}
public function set_config($config) {
foreach ($config as $key => $value) {
$this->$key = $value;
}
return $this;
}
public function upload($field = 'userfile') {
if (empty($this->upload_path)) {
$this->set_error('upload_path_not_set');
return FALSE;
}
if (!realpath(FCPATH . $this->upload_path)) {
$this->set_error('upload_path_in_correct');
return FALSE;
}
if (!empty($this->files[$field]['name'][0])) {
$check_error = 0;
foreach ($this->files[$field]['name'] as $key => $value) {
$this->file_name = $this->files[$field]['name'][$key];
$this->filenames[] = $this->files[$field]['name'][$key];
$this->file_temp = $this->files[$field]['tmp_name'][$key];
$this->file_size = $this->files[$field]['size'][$key];
$this->get_file_extension = explode('.', $this->files[$field]['name'][$key]);
$this->get_file_extension_end = strtolower(end($this->get_file_extension));
if (!in_array($this->get_file_extension_end, $this->allowed_types)) {
$this->set_error('file_extension_not_allowed');
$check_error++;
}
if ($this->files[$field]['size'][$key] > $this->max_size) {
$this->set_error('file_size_check');
$check_error++;
}
if ( ! #copy($this->file_temp, FCPATH . $this->upload_path . '/' . $this->file_name)) {
if ( ! #move_uploaded_file($this->file_temp, FCPATH . $this->upload_path . '/' . $this->file_name)) {
$this->set_error('upload_destination_error', 'error');
$check_error++;
}
}
}
if($check_error > 0 ) {
return FALSE;
}
// This lets me get file data in another function
return $this;
}
}
public function upload_data()
{
$data = array();
foreach($this->filenames as $filename)
{
$data[] = array(
'file_name' => $filename,
'file_path' => FCPATH . $this->upload_path . '/'
);
}
return $data;
}
public function set_error($message) {
$this->CI->lang->load('upload', 'english');
$msg = "";
if ($message == 'upload_path_not_set') {
$msg .= $this->CI->lang->line($message);
}
if ($message == 'upload_path_in_correct') {
$msg .= $this->CI->lang->line($message);
}
if ($message == 'file_extension_not_allowed') {
$msg .= sprintf($this->CI->lang->line($message), $this->file_name, $this->get_file_extension_end);
}
if ($message == 'file_size_check') {
$msg .= sprintf($this->CI->lang->line($message), $this->file_name, $this->max_size);
}
return $this->error_message[] = $msg;
}
public function display_error_messages($open_tag = '<p>', $close_tag = '</p>') {
$message = "";
if (isset($this->error_message)) {
foreach($this->error_message as $msg) {
$message .= $open_tag . $msg . $close_tag;
}
}
return $message;
}
public function clean($data) {
if (is_array($data)) {
foreach ($data as $key => $value) {
unset($data[$key]);
$data[$this->clean($key)] = $this->clean($value);
}
} else {
$data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
}
return $data;
}
}
And
public function index()
{
$data['error'] = '';
$this->load->library('multiple_upload');
$config['upload_path'] = 'uploads';
$config['allowed_types'] = array('jpg', 'png');
$config['max_size'] = 3000000;
//$config['max_size'] = 1000;
$config['overwrite'] = TRUE;
$this->multiple_upload->set_config($config);
if ($this->multiple_upload->upload() == FALSE)
{
$data['error'] = $this->multiple_upload->display_error_messages('<div class="alert alert-danger">', '</div>');
$this->load->view('upload', $data);
}
else
{
$data = $this->multiple_upload->upload_data();
foreach($data as $file)
{
echo $file['file_name']."<br>";
}
}
}
you can use array to save all files information in upload_data function.
public function upload_data() {
$data = array(
'file_name' => $this->file_name,
'file_path' => FCPATH . $this->upload_path . '/'
);
return $data;
}
to
public function upload_data() {
$data[] = array(
'file_name' => $this->file_name,
'file_path' => FCPATH . $this->upload_path . '/'
);
return $data;
}
it will return array of all the file details
On my multiple upload library, I have a set error function.
On my upload function I use a in_array to check file extensions. If the in_array detects error it displays multiple error messages correct.
The problem I am having is for some reason when I use return FALSE; under the $this->set_error('file_extension_not_allowed') then will on display one message. Not sure why return FALSE limits error messages.
Question: How is it possible to use my return false but be able to display multiple message correct.
<?php
class Multiple_upload {
public $set_errors = array();
public function __construct($config = array()) {
$this->CI =& get_instance();
$this->files = $this->clean($_FILES);
empty($config) OR $this->set_config($config);
}
public function set_config($config) {
foreach ($config as $key => $value) {
$this->$key = $value;
}
return $this;
}
public function upload($field = 'userfile') {
$allowed_extension = explode('|', $this->allowed_types);
if (empty($this->upload_path)) {
$this->set_error('upload_path_not_set', 'upload_path_check');
return FALSE;
}
if (!realpath(FCPATH . $this->upload_path)) {
$this->set_error('upload_path_in_correct', 'location_check');
return FALSE;
}
if (!empty($this->files[$field]['name'][0])) {
foreach ($this->files[$field]['name'] as $key => $value) {
$this->file_name = $this->files[$field]['name'][$key];
$get_file_extension = explode('.', $this->files[$field]['name'][$key]);
$this->get_file_extension_end = strtolower(end($get_file_extension));
$array_1 = array(
$allowed_extension,
);
$array_2 = array(
$get_file_extension[1],
);
if (!in_array($array_2, $array_1)) {
$this->set_error('file_extension_not_allowed', 'extension_check');
return FALSE;
}
}
return $this;
}
}
public function set_error($message, $type) {
$this->CI->lang->load('upload', 'english');
$this->error_message[] = $this->CI->lang->line($message);
return $this;
}
public function display_error_messages($open_tag = '<p>', $close_tag = '</p>') {
foreach($this->error_message as $msg) {
var_dump($msg);
}
}
public function clean($data) {
if (is_array($data)) {
foreach ($data as $key => $value) {
unset($data[$key]);
$data[$this->clean($key)] = $this->clean($value);
}
} else {
$data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
}
return $data;
}
}
Maybe this can help...
public function upload($field = 'userfile')
{
$allowed_extension = explode('|', $this->allowed_types);
if (empty($this->upload_path))
{
$this->set_error('upload_path_not_set', 'upload_path_check');
return FALSE;
}
if (!realpath(FCPATH . $this->upload_path))
{
$this->set_error('upload_path_in_correct', 'location_check');
return FALSE;
}
if (!empty($this->files[$field]['name'][0]))
{
$check_error = 0;//added this
foreach ($this->files[$field]['name'] as $key => $value)
{
$this->file_name = $this->files[$field]['name'][$key];
$get_file_extension = explode('.', $this->files[$field]['name'][$key]);
$this->get_file_extension_end = strtolower(end($get_file_extension));
$array_1 = array(
$allowed_extension,
);
$array_2 = array(
$get_file_extension[1],
);
if (!in_array($array_2, $array_1))
{
$this->set_error('file_extension_not_allowed', 'extension_check');
$check_error++;
}
}
if($check_error > 0 )
{
return FALSE;
}
return $this;
}
}
Hi
i have problem with the final_price,min_price,max_price in the catalog_product_index_price table its is wrongly inserting the values after function save() during import.
The file is app\code\core\Mage\Catalog\Model\Convert\Adapter\Product.php
The control goes to finish() function
public function finish()
{
Mage::dispatchEvent('catalog_product_import_after', array());
$entity = new Varien_Object();
Mage::getSingleton('index/indexer')->processEntityAction(
$entity, self::ENTITY, Mage_Index_Model_Event::TYPE_SAVE
);
}
where is the insert statement to insert the value in the catalog_product_index_price table?
How this can be resolved?
My saveRow fucnction to populate database.My excel sheet contains the following additional row
Price Type:radio:1
Unit Price:absolute:2691|Case Price:absolute:12420
Unit Price:absolute:762|Case Price:absolute:7029
The save database function is
public function saveRow(array $importData)
{
$product = $this->getProductModel()
->reset();
if (empty($importData['store'])) {
if (!is_null($this->getBatchParams('store'))) {
$store = $this->getStoreById($this->getBatchParams('store'));
} else {
$message = Mage::helper('catalog')->__('Skipping import row, required field "%s" is not defined.', 'store');
Mage::throwException($message);
}
}
else {
$store = $this->getStoreByCode($importData['store']);
}
if ($store === false) {
$message = Mage::helper('catalog')->__('Skipping import row, store "%s" field does not exist.', $importData['store']);
Mage::throwException($message);
}
if (empty($importData['sku'])) {
$message = Mage::helper('catalog')->__('Skipping import row, required field "%s" is not defined.', 'sku');
Mage::throwException($message);
}
$product->setStoreId($store->getId());
$productId = $product->getIdBySku($importData['sku']);
if ($productId) {
$product->load($productId);
}
else {
$productTypes = $this->getProductTypes();
$productAttributeSets = $this->getProductAttributeSets();
/**
* Check product define type
*/
if (empty($importData['type']) || !isset($productTypes[strtolower($importData['type'])])) {
$value = isset($importData['type']) ? $importData['type'] : '';
$message = Mage::helper('catalog')->__('Skip import row, is not valid value "%s" for field "%s"', $value, 'type');
Mage::throwException($message);
}
$product->setTypeId($productTypes[strtolower($importData['type'])]);
/**
* Check product define attribute set
*/
if (empty($importData['attribute_set']) || !isset($productAttributeSets[$importData['attribute_set']])) {
$value = isset($importData['attribute_set']) ? $importData['attribute_set'] : '';
$message = Mage::helper('catalog')->__('Skip import row, the value "%s" is invalid for field "%s"', $value, 'attribute_set');
Mage::throwException($message);
}
$product->setAttributeSetId($productAttributeSets[$importData['attribute_set']]);
foreach ($this->_requiredFields as $field) {
$attribute = $this->getAttribute($field);
if (!isset($importData[$field]) && $attribute && $attribute->getIsRequired()) {
$message = Mage::helper('catalog')->__('Skipping import row, required field "%s" for new products is not defined.', $field);
Mage::throwException($message);
}
}
}
$this->setProductTypeInstance($product);
if (isset($importData['category_ids'])) {
$product->setCategoryIds($importData['category_ids']);
}
foreach ($this->_ignoreFields as $field) {
if (isset($importData[$field])) {
unset($importData[$field]);
}
}
if ($store->getId() != 0) {
$websiteIds = $product->getWebsiteIds();
if (!is_array($websiteIds)) {
$websiteIds = array();
}
if (!in_array($store->getWebsiteId(), $websiteIds)) {
$websiteIds[] = $store->getWebsiteId();
}
$product->setWebsiteIds($websiteIds);
}
if (isset($importData['websites'])) {
$websiteIds = $product->getWebsiteIds();
if (!is_array($websiteIds)) {
$websiteIds = array();
}
$websiteCodes = explode(',', $importData['websites']);
foreach ($websiteCodes as $websiteCode) {
try {
$website = Mage::app()->getWebsite(trim($websiteCode));
if (!in_array($website->getId(), $websiteIds)) {
$websiteIds[] = $website->getId();
}
}
catch (Exception $e) {}
}
$product->setWebsiteIds($websiteIds);
unset($websiteIds);
}
$custom_options = array();
foreach ($importData as $field => $value) {
if (in_array($field, $this->_inventoryFields)) {
continue;
}
if (in_array($field, $this->_imageFields)) {
continue;
}
$attribute = $this->getAttribute($field);
if (!$attribute) {
/* CUSTOM OPTION CODE */
if(strpos($field,':')!==FALSE && strlen($value)) {
$values=explode('|',$value);
if(count($values)>0) {
#list($title,$type,$is_required,$sort_order) = explode(':',$field);
$title = ucfirst(str_replace('_',' ',$title));
$custom_options[] = array(
'is_delete'=>0,
'title'=>$title,
'previous_group'=>'',
'previous_type'=>'',
'type'=>$type,
'is_require'=>$is_required,
'sort_order'=>$sort_order,
'values'=>array()
);
foreach($values as $v) {
$parts = explode(':',$v);
$title = $parts[0];
if(count($parts)>1) {
$price_type = $parts[1];
} else {
$price_type = 'fixed';
}
if(count($parts)>2) {
$price = $parts[2];
} else {
$price =0;
}
if(count($parts)>3) {
$sku = $parts[3];
} else {
$sku='';
}
if(count($parts)>4) {
$sort_order = $parts[4];
} else {
$sort_order = 0;
}
switch($type) {
case 'file':
/* TODO */
break;
case 'field':
case 'area':
$custom_options[count($custom_options) - 1]['max_characters'] = $sort_order;
/* NO BREAK */
case 'date':
case 'date_time':
case 'time':
$custom_options[count($custom_options) - 1]['price_type'] = $price_type;
$custom_options[count($custom_options) - 1]['price'] = $price;
$custom_options[count($custom_options) - 1]['sku'] = $sku;
break;
case 'drop_down':
case 'radio':
case 'checkbox':
case 'multiple':
default:
$custom_options[count($custom_options) - 1]['values'][]=array(
'is_delete'=>0,
'title'=>$title,
'option_type_id'=>-1,
'price_type'=>$price_type,
'price'=>$price,
'sku'=>$sku,
'sort_order'=>$sort_order,
);
break;
}
}
}
}
/* END CUSTOM OPTION CODE */
continue;
}
$isArray = false;
$setValue = $value;
if ($attribute->getFrontendInput() == 'multiselect') {
$value = explode(self::MULTI_DELIMITER, $value);
$isArray = true;
$setValue = array();
}
if ($value && $attribute->getBackendType() == 'decimal') {
$setValue = $this->getNumber($value);
}
if ($attribute->usesSource()) {
$options = $attribute->getSource()->getAllOptions(false);
if ($isArray) {
foreach ($options as $item) {
if (in_array($item['label'], $value)) {
$setValue[] = $item['value'];
}
}
} else {
$setValue = false;
foreach ($options as $item) {
if ($item['label'] == $value) {
$setValue = $item['value'];
}
}
}
}
$product->setData($field, $setValue);
}
if (!$product->getVisibility()) {
$product->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE);
}
$stockData = array();
$inventoryFields = isset($this->_inventoryFieldsProductTypes[$product->getTypeId()])
? $this->_inventoryFieldsProductTypes[$product->getTypeId()]
: array();
foreach ($inventoryFields as $field) {
if (isset($importData[$field])) {
if (in_array($field, $this->_toNumber)) {
$stockData[$field] = $this->getNumber($importData[$field]);
}
else {
$stockData[$field] = $importData[$field];
}
}
}
$product->setStockData($stockData);
$imageData = array();
foreach ($this->_imageFields as $field) {
if (!empty($importData[$field]) && $importData[$field] != 'no_selection') {
if (!isset($imageData[$importData[$field]])) {
$imageData[$importData[$field]] = array();
}
$imageData[$importData[$field]][] = $field;
}
}
foreach ($imageData as $file => $fields) {
try {
$product->addImageToMediaGallery(Mage::getBaseDir('media') . DS . 'import' . trim($file), $fields);
}
catch (Exception $e) {}
}
$product->setIsMassupdate(true);
$product->setExcludeUrlRewrite(true);
$product->save();
/* Remove existing custom options attached to the product */
foreach ($product->getOptions() as $o) {
$o->getValueInstance()->deleteValue($o->getId());
$o->deletePrices($o->getId());
$o->deleteTitles($o->getId());
$o->delete();
}
/* Add the custom options specified in the CSV import file */
if(count($custom_options)) {
foreach($custom_options as $option) {
try {
$opt = Mage::getModel('catalog/product_option');
$opt->setProduct($product);
$opt->addOption($option);
$opt->saveOptions();
}
catch (Exception $e) {}
}
}
return true;
}
This section of the code has been quite well tested, so it's unlikely (though conceivable) that this is a bug that you need to correct in the indexer. Can you provide more detail about the discrepancy that you are seeing?
There is a very good chance that you are seeing unexpected results because of some product being enabled/disabled, etc etc.