I'm using Maatwebsite in Laravel and it's very good option for excel works but I have one problem .. I have excel sheet with arabic heading, so when I import it , it converted to understand-less english character to fit array key .. So What is the solution for my problem?
I know it's too late, but for someone else that may have the same problem, you should change the value of "heading" key to "original" in "import" array of config/excel.php file..
'import' => [
...
'heading' => 'original',
],
http://www.maatwebsite.nl/laravel-excel/docs/import
Look up the header about import encoding.
From thoose pages:
// When utilising a closure, you can pass the input encoding as third parameter.
Excel::load('filename.csv', function($reader) {
}, 'UTF-8');
// or without a closure, you can use it as second parameter.
Excel::load('filename.csv', 'UTF-8');
Does that solve the issue?
You can implements the Interface of WithCustomCsvSettings, in your class import
Example:
<?php
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithCustomCsvSettings;
class ArticlesImport implements ToCollection, WithCustomCsvSettings
{
public function collection(Collection $rows)
{
// do something
}
public function getCsvSettings(): array
{
# Define your custom import settings for only this class
return [
'input_encoding' => 'UTF-8',
'delimiter' => ";"
];
}
}
I'm too late but this workerd for me, instead of a modifying import.php, in your controller add this
config(['excel.import.heading' => 'original' ]);
Related
I'm still new to Laravel and I needed some help.
I have a job from a programming course that I'm stuck on, which is to import a .csv file like in the image: enter image description here
And I need to add it to the database without duplicating the CPF information as in the image:
enter image description here
*The information is merely illustrative.
So if anyone can help me I would appreciate it.
I can use updateOrCreate but it doesn't get the rest of the information.
Import:
public function collection(Collection $collection)
{
foreach ($collection as $row) {
Clientes::updateOrCreate(
[ 'cpf' => $row[1]],
[ 'nome' => $row[2],
'telefone1' => $row[0],
]
);
}
}
Controller:
public function import(Request $request)
{
$import = (new ImportTelefones(2));
Excel::import($import, $request->file);
return redirect()->back();
}
It looks like that you are trying to import an Excel or CSV file.
The easiest option for that is to use Laravel-Excel Package.
See here:
Installation: https://docs.laravel-excel.com/3.1/getting-started/installation.html
Import: https://docs.laravel-excel.com/3.1/imports/
With that you should be able to import your file and have the data in the database.
To prevent duplicates you can use the 'upsert' feature. It will update the entry on import instead of creating it, if the configured unique key exists.
https://docs.laravel-excel.com/3.1/imports/model.html#upserting-models
Best regards
Sergej
Hi i'm using Maatwerk Excel laravel package to export data to XLSX and CSV.
In 2 instances a comma is good.
But now i need to make a CSV where the delimeter is not a comma but something different (a tab or pipe symbol).
I cannot find where to set this.
I tried:
Config::set('Excel::csv.delimeter','|');
Excel::create('CSV Products', function($excel) use ($exports_arr) {
$excel->setTitle('Products');
$excel->setCreator('Me')->setCompany('My company');
$excel->setDescription('Products');
$excel->sheet('sheet1', function($sheet) use ($exports_arr) {
$sheet->fromArray($exports_arr, null, 'A1', false, false);
});
})->download('csv');
But if i look in the config/Excel.php file the comments suggest that this delimeter is only for reading.
Is it even possible to change the Delimeter for EXPORTING CSV files?
Thanks in advance.
The comment states that excel.csv.delimiter is used for reading out a csv file, but in Writers/LaravelExcelWriter.php (line 578) the CSV delimiter is taken from the config, and set as , by default:
$this->writer->setDelimiter(config('excel.csv.delimiter', ','));
Are you sure the Config::set statement works properly?
Try to use:
Config::set('excel.csv.delimeter','|');
and check the value with
Config::get('excel.csv.delimeter');
UPDATE:
As mentioned in this answer, the service provider is registered before the request takes place. Updating the config key during the request won't affect the value that is read earlier by Maatwerk/Excel. A solution is given in the answer, by creating a deferred provider.
I know this is a bit outdated but I was having the same problem recently.
In order to set a custom delimiter while exporting multiple CSV files, you can create a new instance of the use Maatwebsite\Excel\Excel class without using the facade.
Try this:
use Maatwebsite\Excel\Excel;
use Maatwebsite\Excel\Writer;
use Maatwebsite\Excel\QueuedWriter;
use Maatwebsite\Excel\Reader;
...
$reader = new Reader(app()->make('filesystem'));
$writer = new Writer;
$queued_writer = new QueuedWriter($writer);
$writer->setDelimiter('|');
$excel = new Excel($writer, $queued_writer, $reader, app()->make('filesystem'));
$excel->create( ... );
An update on this question: If you are using Laravel Excel 3, you can set it in the config/excel.php file:
return [
'exports' => [
'csv' => [
'delimiter' => '|',
]
]
]
Or if you want to set it dynamically:
\Config::set('excel.exports.csv.delimiter', '|');
use Maatwebsite\Excel\Concerns\WithCustomCsvSettings;
use Maatwebsite\Excel\Concerns\WithCustomQuerySize;
class MyExportClass implements FromView, WithCustomQuerySize, WithCustomCsvSettings
{
use Exportable;
public string $filePath;
public string $disk;
public function getCsvSettings(): array
{
return [
'delimiter' => ",",
];
}
....
}
From documentation:
enter link description here
I'm working with Yii2 Framework, and already configured i18n component using this guide:
http://thecodeninja.net/2014/12/i18n-with-yii-2-advanced-template/
So, I can now translate strings within my php files using Yii::t() function. Translatable strings are extracted using $ ./yii message/extract console command, which generates proper translation files.
I now need to display translations for strings stored in the database.
I could use Yii:t() with a variable instead of a string as an argument like this
echo Yii:t('app', $some_string_from_db );
and make a new php file with some code like this
<?php
function dbStringsToTranslate() {
$o = Yii::t('app','db english string 1');
$o.= Yii::t('app','db english string 2');
$o.= Yii::t('app','db english string 3');
return $o;
}
This way $ ./yii message/extract command will find the needed translations.
This is working Ok, but of course $ ./yii message/extract is throwing some warnings anywhere I use Yii:t() with variables.
Skipping line 39. Make sure both category and message are static strings.
I think this is not a big deal, but well, here is my question:
Is this a right way to translate strings stored in a database?
Is there a better way to accomplish this?
You can check out this extension. https://github.com/creocoder/yii2-translateable it allows for attaching behaviors to models to support multiple languages.
I am using it now in a projects and it is easy to use.
I was having the same problem, and I found the solution with this module. In the module configuration you have the 'tables' array, in which you can specify which field(s) of which table(s) should be translated.
Then, the module has its own 'scan' action (equivalent to message/extract) with which it adds all the translatable strings to database (using DbMessageSource): all Yii::t, the specified database fields, and many more (even javascript, check the docs). It also has a nice user interface to do the translations, it's awesome!
For example, with the following configuration the field name from table nationality will be scanned and added for its translation (i.e country names):
'modules' => [
'translatemanager' => [
'class' => 'lajax\translatemanager\Module',
...
'tables' => [ // Properties of individual tables
[
'connection' => 'db', // connection identifier
'table' => 'nationality', // table name
'columns' => ['name'], // names of multilingual fields
'category' => 'database-table-name',// the category is the database table name
'categoryPrefix' => 'lx-' //
]
]
],
],
You can generate php file with some fake Yii:t() calls.
For example:
$filename = Yii::getAlias('#frontend/runtime/fake-category-translations.php');
$str = '<?php' . PHP_EOL;
foreach (Category::find()->all() as $category) {
$str .= "Yii::t('category', '{$category->name}');" . PHP_EOL;
}
file_put_contents($filename, $str);
In output this file will be something like this:
<?php
Yii::t('category', 'Art & Design');
Yii::t('category', 'Creativity');
Yii::t('category', 'Educational');
Yii::t('category', 'Education');
Yii::t('category', 'Lifestyle');
Yii::t('category', 'Casual');
So, now you can just call console method for searching untranslated strings:
php yii message/extract #frontend/messages/config.php
I know this is old but I faced same thing with rest API, and here is how I went about resolving it. Note that When saving I used
$post->comment = Yii::t('app', 'My Nice Comment here');
$post->save();
class Post extends ActiveRecord
{
public function fields()
{
$fields = parent::fields();
$fields['comment'] = function ($model) {
return Yii::t('app', $model->comment);
};
return $fields;
}
}
I just started working with Laravel. I need to rewrite a whole system I made some years ago, using Laravel 4 as base framework. In my old system, I used to have a constant.php file with some constants declared, and a globals.php file which contained lots of array sets (for example, categories statuses, type of events, langs, etc.). By doing so, I could use something like
foreach ( $langs as $code => $domain ) {
// Some stuff
}
anywhere in my app.
My question is, how can I store that info in the so called "laravel way". I tried using some sort of object to store this info, setting this as a service and creating for it a facade:
app/libraries/Project/Constants.php
namespace PJ;
class Constants {
public static $langs = [
'es' => 'www.domain.es',
'en' => 'www.domain.us',
'uk' => 'www.domain.uk',
'br' => 'www.domain.br',
'it' => 'www.domain.it',
'de' => 'www.domain.de',
'fr' => 'www.domain.fr'
];
}
app/libraries/Project/ConstantsServiceProvider.php
namespace PJ;
use Illuminate\Support\ServiceProvider;
class ConstantsServiceProvider extends ServiceProvider {
public function register() {
$this->app->singleton('PJConstants', function() {
return new Constants;
});
}
}
app/libraries/Project/ConstantsFacade.php
namespace PJ;
use Illuminate\Support\Facades\Facade;
class ConstantsFacade extends Facade {
protected static function getFacadeAccessor() {
return 'PJConstants';
}
}
composer.json
"psr-4": {
"PJ\\": "app/libraries/Project"
},
and so I access that property as PJ\Constants::$langs.
This works, but I doubt it is the most efficient or correct way of doing it. I mean, is it the right way to "propagate" a variable by creating a whole Service Provider and facades and all such stuff? Or where should I put this data?
Thanks for any advice.
EDIT # 01
Data I want to pass to all controllers and views can be directly set in script, like in the example at the beginning of my post, but it can also be generated dynamically, from a database for example. This data could be a list of categories. I need them in all views to generate a navigation bar, but I also need them to define some routing patterns (like /category/subcategory/product), and also to parse some info in several controllers (Like get info from the category that holds X product).
My array is something like:
$categories = [
1 => ['name' => 'General', 'parent' => 0, 'description' => 'Lorem ipsum...'],
2 => ['name' => 'Nature', 'parent' => 0, 'description' => 'Lorem ipsum...'],
3 => ['name' => 'World', 'parent' => 0, 'description' => 'Lorem ipsum...'],
4 => ['name' => 'Animals', 'parent' => 2, 'description' => 'Lorem ipsum...']
]
Just as an example. Index is the id of the category, and the Value is info associated with the category.
I need this array, also, available in all Controllers and Views.
So, should I save it as a Config variable? How else could I store these data; what would be the best and semantically correct way?
For most constants used globally across the application, storing them in config files is sufficient. It is also pretty simple
Create a new file in the app/config directory. Let's call it constants.php
In there you have to return an array of config values.
return [
'langs' => [
'es' => 'www.domain.es',
'en' => 'www.domain.us'
// etc
]
];
And you can access them as follows
Config::get('constants.langs');
// or if you want a specific one
Config::get('constants.langs.en');
And you can set them as well
Config::set('foo.bar', 'test');
Note that the values you set will not persist. They are only available for the current request.
Update
The config is probably not the right place to store information generated from the database. You could just use an Eloquent Model like:
class Category extends Eloquent {
// db table 'categories' will be assumed
}
And query all categories
Category::all();
If the whole Model thing for some reason isn't working out you can start thinking about creating your own class and a facade. Or you could just create a class with all static variables and methods and then use it without the facade stuff.
For Constants
Create constants.php file in the config directory:-
define('YOUR_DEFINED_CONST', 'Your defined constant value!');
return [
'your-returned-const' => 'Your returned constant value!'
];
You can use them like:-
echo YOUR_DEFINED_CONST . '<br>';
echo config('constants.your-returned-const');
For Static Arrays
Create static_arrays.php file in the config directory:-
class StaticArray
{
public static $langs = [
'es' => 'www.domain.es',
'en' => 'www.domain.us',
'uk' => 'www.domain.uk',
'br' => 'www.domain.br',
'it' => 'www.domain.it',
'de' => 'www.domain.de',
'fr' => 'www.domain.fr'
];
}
You can use it like:-
echo StaticArray::$langs['en'];
Note: Laravel includes all config files automatically, so no need of manual include :)
Create common constants file in Laravel
app/constants.php
define('YOUR_CONSTANT_VAR', 'VALUE');
//EX
define('COLOR_TWO', 'red');
composer.json
add file location at autoload in composer.json
"autoload": {
"files": [
"app/constants.php"
]
}
Before this change can take effect, you must run the following command in Terminal to regenerate Laravel’s autoload files:
composer dump-autoload
For global constants in Laravel 5, I don't like calling Config for them. I define them in Route group like this:
// global contants for all requests
Route::group(['prefix' => ''], function() {
define('USER_ROLE_ADMIN','1');
define('USER_ROLE_ACCOUNT','2');
});
I think the best way is to use localization.
Create a new file messages.php in resources/lang/en (en because that is what is set in my config/app 'locale'=>'en')
return an array of all your values
return [
'welcome' => 'Welcome to our application'
];
to retrieve for laravel 5.3 and below
echo trans('messages.welcome');
or
echo Lang::get('messages.welcome');
for 5.4 use
echo __('messages.welcome')
laravel 5.0 localization
or
laravel 5.4 localization
Just to add to the above answer you will have to include the config class before you could start using it in Laravel 5.3
use Illuminate\Support\Facades\Config;
Atleast in Laravel 5.4, in your constructor you can create them;
public function __construct()
{
\Config::set('privileged', array('user1','user2');
\Config::set('SomeOtherConstant', 'my constant');
}
Then you can call them like this in your methods;
\Config::get('privileged');
Especially useful for static methods in the Model, etc...
Reference on Laracasts.com https://laracasts.com/discuss/channels/general-discussion/class-apphttpcontrollersconfig-not-found
Just put a file constants.php file into the config directory and define your constants in that file, that file will be auto loaded,
Tested in Laravel 6+
Create a constants class:
<?php
namespace App\Support;
class Constants {
/* UNITS */
public const UNIT_METRIC = 0;
public const UNIT_IMPERIAL = 1;
public const UNIT_DEFAULT = UNIT_METRIC;
}
Then use it in your model, controller, whatever:
<?php
namespace App\Models;
use App\Support\Constants;
class Model
{
public function units()
{
return Constants::UNIT_DEFAULT;
}
}
I am using ZF2 for my project. And this is an e-commerce site. So I am dealing with currencies.
In ZF2 there is a view helper named currencyFormat()
I am from Turkey so my main currency format is TRY (This is the ISO code of Turkish Lira). But in Turkey we do not use TRY as Currency icon. The icons are "$" for USD, € for "EUR" and "TL" for Turkish Lira (TRY).
So when I format a currency for TRY I am doing it like this in view script:
<?php
echo $this->currencyFormat(245.40, 'TRY', 'tr_TR');
?>
The result of this code is "245.40 TRY". But it has to be "245.40 TL"
Is there a way to solve this? I do not want to use replacement function.
I'm guessing when you say I do not want to use replacement function you mean it would be laborious to do a str_replace every time you call the helper. The solution would be to replace the helper with your own. Here's a quick how to
First create a helper of your own which extends the existing helper and handles the replacement if necessary...
<?php
namespace Application\View\Helper;
use Zend\I18n\View\Helper\CurrencyFormat;
class MyCurrencyFormat extends CurrencyFormat
{
public function __invoke(
$number,
$currencyCode = null,
$showDecimals = null,
$locale = null
) {
// call parent and get the string
$string = parent::__invoke($number, $currencyCode, $showDecimals, $locale);
// format to taste and return
if (FALSE !== strpos($string, 'TRY')) {
$string = str_replace('TRY', 'TL', $string);
}
return $string;
}
}
Then in Module.php, implement the ViewHelperProviderInterface, and provide it with details of your helper
//Application/Module.php
class Module implements \Zend\ModuleManager\Feature\ViewHelperProviderInterface
{
public function getViewHelperConfig()
{
return array(
'invokables' => array(
// you can either alias it by a different name, and call that, eg $this->mycurrencyformat(...)
'mycurrencyformat' => 'Application\View\Helper\MyCurrencyFormat',
// or if you want to ALWAYS use your version of the helper, replace the above line with the one below,
//and all existing calls to $this->currencyformat(...) in your views will be using your version
// 'currencyformat' => 'Application\View\Helper\MyCurrencyFormat',
),
);
}
}
As of 1 March 2012 sign for Turkish Lira is TRY. http://en.wikipedia.org/wiki/Turkish_lira
So ZF outputs it right I think.