Generate files with laravel command - laravel

I need to create a number of files in a specific format. So I planned to create a generate command by extending GeneratorCommand. I want to create view files and view-config files in application root directory.
The problem is, I did not find any official doc to do so. There are some article in the web, which suggests to use getDefaultNamespace method to set the path like the following. I was following the steps suggested at https://laravelpackage.com/06-artisan-commands.html#creating-a-generator-command. But I want to create files in root dir not into app dir. When i remove the $rootNamespace form the method it does not create files.
protected function getDefaultNamespace($rootNamespace)
{
return $rootNamespace.'\Actions';
}
how can i create a command to generate files in specific directories in the application?

The class GeneratorCommand has a protected method rootNamespace. If I understand correctly, it returns the root ouf your application.
So you should be able to override the method getNamespace like so:
/**
* Get the full namespace for a given class, without the class name.
*
* #param string $name
* #return string
*/
protected function getNamespace($name)
{
$rootNamespace = trim($this->rootNamespace(), '\\');
return $this->getDefaultNamespace($rootNamespace);
}
NOTE
You can see a working example in one of my open source projects.

Related

How to replace phpdocs with new attributes in php 8

I am using laravel. I need to know how phpdoc can be written in php 8 with attibutes.
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
//Some code
return [];
}
Can someone please explain how the above code can be written with attributes.
I believe you have misunderstood what Attributes are for, and how they related to doc blocks. There are two common uses of doc blocks (comments marked with /** ... */):
To document the code (hence the name "doc block"), in a mostly-standardised way which can be read by various tools, including documentation generators and IDEs.
To add machine-readable annotations to the code, for use with libraries and frameworks that can automatically generate behaviour based on those. For instance, an ORM might use an annotation of #TableName('Foo') to link a class to a particular database table, and generate appropriate SQL.
The example you've shown is of the first usage. What you have written is still the correct way of writing documentation.
PHP 8's native Attributes replace the second usage. It's up to the library what Attributes to look for, but an ORM that previously looked for #TableName('Foo') in a docblock might now look for #[TableName('Foo')] as a native Attribute instead.
There is a great automatic refractoring tool called rector. It will make your life so much easier. Install it, then create a rector.php file at the root directory that should look like something like this:
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Rector\Doctrine\Set\DoctrineSetList;
use Rector\Symfony\Set\SensiolabsSetList;
use Rector\Symfony\Set\SymfonySetList;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([
__DIR__ . '/src',
__DIR__ . '/tests'
]);
$rectorConfig->sets([
DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES,
SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES,
SensiolabsSetList::FRAMEWORK_EXTRA_61,
]);
};
There are plenty of configuration options that you can find in the docs.
When you are done, just run the refractoring tool:
vendor/bin/rector process src

Laravel Bagisto create custom Core.php

I am trying to customize bagisto, and hit a wall when trying to customize Core.php file.
What I want to do is edit some of the functions inside the Core.php file. I am now editing the file directly, but this is definitely not optimal.
How am I supposed to override some of the functions inside the Core.php?
I couldn't find any complete procedure online and am new to Laravel, so I'm completely lost.
To be precise I want to override the currency function like this:
public function currency($amount = 0)
{
if (is_null($amount)) {
$amount = 0;
}
return intval($amount);
//return $this->formatPrice($this->convertPrice($amount), $this->getCurrentCurrency()->code);
}
Found it (I got helped).
The Core.php is called from Core/src/Http/helpers.php which creates the function core().
This function is then made public to all in package.lock under "autoload".
To customize the Core file you would have to create a custom Core file and helper file (that calls the custom Core file) then change the composer.lock file and make it call your custom helper.

response()->file() does not find files located at storage/app

This works perfectly:
return Storage::download('my_documents','test.pdf');
This doesn't work ("file not found error"):
return response()->file('/storage/app/my_documents/test.pdf');
How exactly do I have to define the path for the second approach?
I want to show the file directly in the browser. Can Storage class offers that functionality?
Please share solutions for Laravel 8+.
Thanks.
You must provide an absolute path to the file() method. You can use
storage_path() as configured in your config/filesystems.php file.
return response()->file(storage_path('app/my_documents/test.pdf'));
This should also work:
return response(file(storage_path('app/my_documents/test.pdf'));
Note: If you ever use the app/public folder, make sure you don't forget to create a symbolic link to your app public folder:
php artisan storage:link
For file return need to specify full path like below.For example in this case file exist in storage/app/public/pdf/1621869239k9y3aBE.pdf
return response()->file(storage_path('app/public/pdf/1621869239k9y3aBE.pdf'));
file() method accept two parameter like below
/**
* Return the raw contents of a binary file.
*
* #param \SplFileInfo|string $file
* #param array $headers
* #return \Symfony\Component\HttpFoundation\BinaryFileResponse
*/
public function file($file, array $headers = []);
Yes, Storage facade class has this functionality.
You can use method response instead of download. This sends a file directly to the browser instead of download.
In your case it will look like this:
return Storage::response('my_documents','test.pdf');

Move or copy a file from the request to multiple locations

I'm using Laravel and taking in input and file uploads. This page takes changes that users want to make to an order. The end goal is to take this input and apply it to multiple orders.
I can reuse the input for each of the orders. But what would be a good way for me to copy that file in the request to multiple directories? For example, as in the documentation, I originally have: $request->file('photo')->move($destinationPath, $fileName); which works fine for one order. But now that I want to apply it to many orders, I can't move that same file from the request anymore since it doesn't exist.
And it looks like the UploadedFile object doesn't have a copy() method. Any ideas would be appreciated. Thank you.
Do not depend on component too much. Keep it simple
$request->file('photo')->move($destination_path, $file_name);
//Add DIRECTORY_SEPARATOR between path and filename if needed
copy($destination_path.$file_name, $new_path.$new_file_name);
If I may make a suggestion assuming these files are going to stay the same (you aren't allowing your users to modify these files by order), I think it makes sense to store one copy of the file on the server and use a database table to determine which orders that file belongs to and manage it all in the table. You may need to create a files table and an file_order table and give it a many to many relationship to your orders table but in the end, if these files are allowed to be large, could save you a lot of space and in my opinion, make it easier to manage.
In Laravel, look at the vendor\laravel\framework\src\Illuminate\Filesystem\Filesystem.php , and I hope you'll get the everything of file, how they manage the files.
How to copy a file, move a file, delete a file everything is described clearly in that.
For copy a file in Laravel, there function is:
/**
* Copy a file to a new location.
*
* #param string $path
* #param string $target
* #return bool
*/
public function copy($path, $target)
{
return copy($path, $target);
}
I think there's nothing to say now.
Just use that
File::copy('file_name_with_full_path', 'target_directory_where_copy');
Hope, it might be helpful for you.

Codeigniter handling lang files?

I know how to use CI lang helper and lang class, but my question is it possible to
use lang files from other directory than SYSTEM, maybe i can make a new folder in root of app and call language files from there?
And other thing, is is good handling of lang files that CI done?
I want to add somthing that user can uplaod lang files, but structure need to be checked, here
is an example
$lang["msg_first_name"] = "First Name";
This is proper lang line, but what if some upload file that looks like this?
$lang["msg_first_name"] = "First Name i "Michael" and i like chocolate";
You see there is two
"
Does that will create error in lang file, or CI handle that, i or must made a custom class
that will handle that error?
Why the your language in the stystem folder it should be inside the application/language folder. And its not really a good idea to upload the language by user. Its a big SECURITY HOLE because any one can upload any script and that will be executed by your code. You never should allow to upload any executable code in your system.
And if you upload a broken file it will cause the php error. So when there is a php error codeigniter cannot do anything about this. Just simply think you are including a php file as normally you would do for any php. So CI doing the same then reading some variable($lang) and assigning to the a class nothing else.
And yes you can use your define folder to load the language you can do this in few way
$this->load->add_package_path('YOUR_PATH');
//so your language will be YOUR_PATH/language/YOUR_LANG_FOLDER(english default)
$this->load->language('language_file'); //user
OR
$this->lang->load('YOUR_LANG_FILE','LANG',FALSE,TRUE,'YOUR_PATH') ;
//look the function description
/**
* Load a language file
*
* #access public
* #param mixed the name of the language file to be loaded. Can be an array
* #param string the language (english, etc.)
* #param bool return loaded array of translations
* #param bool add suffix to $langfile
* #param string alternative path to look for language file
* #return mixed
*/
OR extend the CI_Lang and modify the load function they way you want, to do this you have to create a file `application/core/MY_Lang.php`
class MY_Lang extends CI_Lang {
//OVERWRITE THE FUNCTION
function load($langfile = '', $idiom = '', $return = FALSE, $add_suffix = TRUE, $alt_path = ''){
//MODIFY THE THE CODE FOMR CI_Lang AND SET THE INCLUDE PATH AS YOU WANT
}
}
You may write different language files and load them whenever you want. Read the following link: http://www.sitepoint.com/multi-language-support-in-codeigniter/
The folder you put your files is application/language/[LANG], and then you just call them in your controller, no need to any further modification. It's important note that the files MUST finish with "_lang.php"
About uploading the file, just deploy your language file (must have the same name in the different languages folders) into the folder and just go. What I've done with similar multilanguages files is building a controller which I use to import the languages lines from a CSV files and write the different lines into the language files:
Code | Message
name | Su nombre
surname | Su apellido
With that, you write the whole language file from there, checking for weird symbols. You may even have several columns with different languages, and keep the coherence with it because you overwrite the file every time you launch the importer_language:
Code | MsgSpanish | MsgEnglish
name | Su nombre | Your Name
surname | Su apellido | Your Surname

Resources