Random unique ids - laravel-5

I'm trying to generate something like 6B6E23518 using randomString() which I'm calling inside my controller
function randomString($chars=10) //generate random string
{
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randstring = '';
for ($i = 0; $i < $chars; $i++) {
$randstring .= $characters[rand(0, strlen($characters))];
}
return $randstring;
}
public function store(TicketsCreateRequest $request)
{
$ticket = $user->tickets()->create([
'ticket_hash' => $this->randomString(10),
// ....
]);
}
but this keeps on storing 0 into 'ticket_hash' and nothing gets generated??

Looking at your source code, is randomString() a public method of your controller class or is it a global function declared elsewhere outside of the class? I ask because it's entered above without the public visibility qualifier and with slightly different indentation to the method below it.
If this function is not an instanace method of your class, then your call to $this->randomString() is probably not calling the method you're expecting it to call. If your randomString() function is a global function defined elsewhere you should call it directly (eg. 'ticket_hash' => randomString(10),)
For what it's worth, for random strings like this it might be best to use the Laravel framework's Str class, only because it may be more stable and is definitely more widely used.
The Str::random() method achieves the output you're looking for in this case.

column ticket_hash was an integer type ,changed it to varchar and it works now.

Related

How to use multiple models in one controller

I have six models that I need to get in one instance in my controller. How can I do that?
I have my six models:
CommentaireCritique
CommentaireNews
CommentaireDossier
CommentaireEpisode
CommentaireSerie
CommentaireTrailer
They all have the same structure in my database, and I would like to show the latest comms on one single page. I don't know if it's possible to bind them in a single controller. I tried that, but it's not working.
public function index()
{
$comms = CommentaireCritique::all() && CommentaireNews::all()
&& CommentaireDossier::all() && CommentaireEpisode::all()
&& CommentaireSerie::all() && CommentaireTrailer::all()
->get();
return view('admin.commentaires.index', compact('comms'));
}
just after the namespace , before the class declaration
use yourAppNameSpace/modelName
There is no limits to the number of models you can instantiate in your controller as long as you declare them above correctly.I think what you need is way to merge the result of all the models if that is so, then you have to use the merge method, otherwise can you please clarify a little bit your question.
yes, you can retrieve them at one controller,
you're already halfway there, you should separate on different variable
public function index()
{
$comms = CommentaireCritique::all()
$news = CommentaireNews::all()
$dossier = CommentaireDossier::all()
$episodes = CommentaireEpisode::all()
$series = CommentaireSerie::all()
$trailers = CommentaireTrailer::all()
return view('admin.commentaires.index', compact('comms','news','dossier','episodes','series','trailers'));
}
if you want put them in one variable, you can use collection docs
All of the results from all() function returns laravel collections. So use concat() function to concatenate all those into one collection
public function index()
{
$coms = CommentaireCritique::all()
->concat(CommentaireNews::all())
->concat(CommentaireDossier::all())
->concat(CommentaireEpisode::all())
->concat(CommentaireSerie::all())
->concat(CommentaireTrailer::all());
return view('admin.commentaires.index', compact('comms'));
}

Refactor Repeated Controller Methods in Laravel

I'm a bit confused about my code in Laravel. I have a member that can subscribe to one or more lessons. I have three tables: members, lessons, and lesson_member.
I created a member form, and from this form, I can register the member in the lesson (I need to get the lesson id, and I put the record in the pivot table).
Then I have the lesson form; I can create a new lesson and put inside one or more members (in this case I need the member code).
Those two functions are nearly the same, but the parameters are different. In my solution, I created two different controllers with two different functions.
LessonController
<?php
public function addMember(Request $request)
{
$lessonMember = new LessonMember();
$lessonId = $request->session()->get('lessonId', 1);
if ((!($lessonMember::where('lesson_id', '=', $lessonId)
->where('license_member_id', '=', $request->memberId)
->exists()))) {
$lessonMember->lesson_id = $lessonId;
$lessonMember->license_member_id = $request->memberId;
$lessonMember->save();
$member = LicenseMember::find($request->memberId)->member;
return response()->json(['user_saved' => $member, 'llm' => $lessonMember, 'actualMembers' => $actualMembers]);
}
}
MemberController
<?php
public function addLesson(Request $request)
{
$lessonMember = new LessonMember();
$memberId = $request->session()->get('memberId', 1);
if ((!($lessonMember::where('lesson_id', $request->lessonId)
->where('license_member_id', $memberId)
->exists()))) {
$lessonMember->lesson_id = $request->lessonId;
$lessonMember->license_member_id = $memberId;
$lessonMember->save();
$member = LicenseMember::find($memberId)->member;
return response()->json(['user_saved' => $member, 'llm' => $lessonMember]);
}
}
I have the same problem with the removeFromLesson() method and in the updateLessonMember method, but the solution should be similar. It is for sure not DRY, and I think I have to put some code in the model (or somewhere else), but I don't know how to proceed. I want to refactor to have a clean solution. I read about traits, but I don't know if it's the right way to follow.
LessonController and MemberController extends a BaseController.
Inside that base controller, create a function called add_lesson_member(you can call it whatever you want)
Then you just need to call this function using $this->add_lesson_member() inside your LessonController or MemberController.

Accessing parameters in Request

I have a question about obtaining parameters from Request object.
What is the difference between
$name = $request->name;
OR
$name = $request->input("name");
They show the same behavior. I am asking that from the typing perspective, it is faster to utilize #1 method. But I don't know the difference. Is #1 prone to SQL injections?
Basically, the first case is just a syntactic sugar for the second. In Laravel, Request implements __get magic function to access its internal properties.
public function all()
{
return array_replace_recursive($this->input(), $this->allFiles());
}
public function __get($key)
{
$all = $this->all();
if (array_key_exists($key, $all)) {
return $all[$key];
} else {
return $this->route($key);
}
}
In the first case, if any files were uploaded, Laravel first looks for a property amongst them. And if there is no such param in files or in input, in your first snippet, Laravel also looks for a value amongst route parameters:
To protect your code against SQL injections, you have to use prepared statements/query builder/ORM. You should not escape/change input, so both these functions don't protect you against SQL injections.

Unable to use variable when loading function via $this in CodeIgniter

When calling a function within a class I am using something like this:
protected $_mdl = 'mdl_posts_latest';
function __construct()
{
parent::__construct();
$this->load->model($this->$_mdl);
}
public function index()
{
$offset = 0;
$limit = 5;
$data['p_latest'] = $this->mdl_posts_latest->get_posts_latest($offset, $limit);
...
...
...
.
and it is working.
The problem is when I ry something like:
$data['p_latest'] = $this->$this->$_mdl->get_posts_latest($offset, $limit);
It throws this error:
Object of class Posts_latest could not be converted to a string
because, obviously, this code is wrong: $this->$this->$_mdl->
So, my question is how can I define the name of my modeljust once at the top of my class and then use it as a variable within all calls for calling a function etc.
Because right now I don't know how to do it so it would look like something:
$this->$model->get_something();
When you're loading the model, you should access the member variable like this, without the $ preceding the member variable's name:
$this->load->model($this->_mdl);
You could look into PHP's variable variables and complex (curly) syntax. It would allow you do something like this, where you can use the value of the variable:
$this->{'_mdl'}->get_posts_latest($offset, $limit);
$this->load->model($_mdl);
instead of
$this->load->model($this->$_mdl);
then:
$data['p_latest'] = $this->$_mdl->get_posts_latest($offset, $limit);
or
$md1 = $this->$_md1;
$data['p_latest'] = $md1->get_posts_latest($offset, $limit);

Codeigniter, where to run model save code if not in the destructor?

I have a model that works with one user in the database.
It is designed to do a lot of small changes to the user, so instead of querying the database multiple times I decided to get all of the user's information in the constructor of the model, and then work on that information through out the rest of the model (so instead of updating the database, it would be updating the array I got). Then I would just save that array back to the database in the destructor.
This works fine, but I've been reading a bit more, and it turns out you shouldn't run any non-cleanup code in the destructor (which is where I'm running the update query to the database). So I was curious, is there a better way to do this? Am I missing a better solution?
Thanks, Max
EDIT:
Here is an example of what I am doing (Note: This example is a shopping cart class, not a user class though):
<?php
class cartmodel extends CI_Model
{
private $sessionPrefix = 'Cart_';
private $CartCache = array();
function __construct ()
{
if ($this->session->userdata($this->sessionPrefix.'data') === FALSE)
$this->session->set_userdata($this->sessionPrefix.'data', array());
$this->CartCache = $this->session->userdata($this->sessionPrefix.'data');
parent::__construct();
}
function __destruct ()
{
$this->session->set_userdata($this->sessionPrefix.'data', $this->CartCache);
}
function AddItem ($id, $count)
{
if ($count == 0 || $count == '' || !is_numeric($count))
return;
if (!isset($this->CartCache[$id]))
$this->CartCache[$id] = 0; //Initialize it so that += works
$this->CartCache[$id] += (int)$count;
}
?>
You can directly manipulate session data in your AddItem() method. Something like this:
function AddItem ($id, $count)
{
// UPDATE CartCache VARIABLE
$this->CartCache = $this->session->userdata($this->sessionPrefix.'data');
// YOUR CODE BELOW
if ($count == 0 || $count == '' || !is_numeric($count))
return;
if (!isset($this->CartCache[$id]))
$this->CartCache[$id] = 0; //Initialize it so that += works
$this->CartCache[$id] += (int)$count;
// SAVE CartCache IN SESSION AGAIN
$this->session->set_userdata($this->sessionPrefix.'data', $this->CartCache);
}
This way if you want to manipulate the Cart_data session variable in other methods, you can still do it. Just update the CartCache array in every method and save it again to the session variable once you've done manipulating data in it.

Resources