Laravel 5.2 Validation Help Exist in Database - database

I'm making a simple booking system with the help of Laravel. The times that is booked is for an imaginary car company that rent cars. So you rent a car by booking the time. I'm pretty far into the project and I'm almost finished. I just have a small problem. I dont know how I can make my booked times "not bookable" so to say.
What I want to be unique is the date of the booking. In my migration for the "booked" times (the table is called "times") I have already set the column "date" to be unique:
public function up()
{
Schema::create('times', function (Blueprint $table) {
$table->integer('car_id')->unsigned();
$table->date('date');
$table->timestamps();
$table->primary(array('car_id', 'date'));
});
}
The date "integer" makes it so that it is unique and I can not book it twice. But what I want to do is check if the booked time is in the Carbon time frame of the ten days from present day. Those times is made like this:
$dt = Carbon::now('Europe/Stockholm');
for ($i = 0; $i < 10; $i++) {
$dates[$i] = $dt->addDays(1)->toDateString();
}
Then I send the $dates variable to my view and display them like this:
<ul class="list-group">
#foreach ($dates as $date)
<form method="POST" action="/{{ $car->id }}/time">
{{ csrf_field() }}
<li class="list-group-item">
<input type="hidden" name="date" value="{{ $date }}">
{{ $date }}
<input type="submit" value="Boka" class="btn btn-primary"/>
</li>
</form>
#endforeach
</ul>
So then if I press the "Boka" button the time is put in the "times" table, and because I use relationship I reach it with $car->time, like that I can get all the booked times on that specific car.
I show all the times that are booked like this in my view:
<ul class="list-group">
#foreach ($car->time as $time)
<li class="list-group-item">
{{ $time->date }}
<form method="POST" action="/delete/time/{{ $time->car_id }}/{{ $time->date }}">
{{ method_field('DELETE') }}
{{ csrf_field() }}
<input type="submit" value="Delete" class="btn btn-danger"/>
</form>
</li>
#endforeach
</ul>
So basically what I want to do now is to check if the date from Carbon is in the "times" table I want to remove the "Boka" button from the view..
My teacher tells me to use this code in some way:
$this->validate($request, [
'date' => 'exists:times,date'
]);
I know what this snippet of code does, it checks the request sent if the date from the form exist in the times table on the column date. But I just don't know where to use it. Ive tried in my "TimesController" where I add the dates to the "times" table like this:
public function update(Request $request, Car $car, Time $time) {
$this->validate($request, [
'date' => 'exists:times,date'
]);
$times = new Time;
$times->date = $request->date;
$car->time()->save($times);
return back();
}
But this doesn't work the way I want it to. It checks if the date is in the table, and if it is. It ads it. But the problem is, the date must be unique so I get an error message that says the date isn't unique. That's good but not what I want. So if I add a date that isn't booked yet. It doesn't add the date like it should. I check what error I get by writing this code in my view:
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
And the error it output said: "The selected date is invalid."
So what I get from that is that my validation code checks if the request is in the database then if it is, the date is added. But if the date isn't already in the "times" table it doesn't get added. That is the exact opposite of what I want..
I tried putting it in my CarsController to where I make up the dates with the help of Carbon as I showed earlier. But I just can't get anything out of that..
I know this post is kinda long. But I wanted to get as much information in as possible. I would really appreciate some help.
TL/DR: What I want to do is use the Validate function in Laravel to check if my dates for booking is in the booked "times" table or not. IF it is then I want the "Boka" button do disappear. The date shouldn't be able to be added to the "times" table. Alternatively the "date" could disappear entirely from the dates made with Carbon if it is in the "times" table...
I really don't know what to do so I would appreciate som help. Thanks.
And yeah, english isn't my native language so please don't bash me.

There are many ways to validate your data in Laravel. I will show you some of them, feel free to choose the one you'll like.
First of all, the basics.
You can use the validate method in the controller method of your choice. The official documentation has a nice example of it.
...
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
...
Your validation rule goes in the second parameter of the method, the array with other rules.
However, this is not the only way you can deal with validation.
As the documentation says in the "Other Validation Approaches" section, you can:
manually create a validator with Validator::make();
make a FormRequest to isolate your validation rules (and, eventually, logic) in a separate class;
Hope it helps. :)

Just check after validate method that if it returns true or false and based on that use return back with errors or proceed further.

Related

Wordpress addon to add data to a database and then call the data

I know this question is probably going to get downvoted and I will probably get into trouble but I am hoping someone may be able to help me with my situation.
On my site I use json to download data from an external source, and then I style it beautifully.
Within the json data is an individual ID for each data set.
What I want to accomplish is to have a database where I can insert the ID and a url link.
I have created the table within the wordpress database via phpMyAdmin, but I want to create a page within the admin section where I can simply add the data in.
For displaying the json data I use a php insert addon, within that php clip i want to do a piece of code that checks the database for the id within my custom database and displays the link.
I will be honest I don't know where to start on this, even if its just a link to a source that shows me how to create an admin page and submit data to the database within wordpress dashboard.
I really appreciate any help given and like I say I know I should try harder, but when ever I do a search all I get is 100's of references to add an admin to the database manually.
Thanks,
Adam
Edit I just realized I never put any table information in my question.
The table name within wordpress is called: wp_home_tickets
within that are 3 fields: id (auto increasement), gameid (numeric) and ticketlink (text)
thanks.
For adding a custom settings page in your admin, use the Settings API https://codex.wordpress.org/Settings_API
Here is a nice tutorial using it https://deliciousbrains.com/create-wordpress-plugin-settings-page/#wp-settings-api
To fetch data from your custom table, use the wpdb class https://developer.wordpress.org/reference/classes/wpdb/. More specifically, you can use wpdb::get_results if you will have multiple rows sharing the same id https://developer.wordpress.org/reference/classes/wpdb/get_results/
Or wpdb::get_row if you will ever only have one https://developer.wordpress.org/reference/classes/wpdb/get_row/
Hope this helps you out!
For anyone wishing to see how it was done, here is how I did it.
I created a file in my theme called db_admin_menu.php and added the following to it:
<?php
function ticket_admin_menu() {
global $team_page;
add_menu_page( __( 'Tickets', 'sports-bench' ), __( 'Tickets', 'sports-bench' ), 'edit_posts', 'add_data', 'ticket_page_handler', 'dashicons-groups', 6 ) ;
}
add_action( 'admin_menu', 'ticket_admin_menu' );
function ticket_page_handler() {
$table_name = 'wp_home_tickets';
global $wpdb;
echo '<form method="POST" action="?page=add_data">
<label>Team ID: </label><input type="text" name="gameid" /><br />
<label>Ticket Link: </label><input type="text" name="ticketlink" /><br />
<input type="submit" value="submit" />
</form>';
$default = array(
'gameid' => '',
'ticketlink' => '',
);
$item = shortcode_atts( $default, $_REQUEST );
$gameid = $item['gameid'];
if ($wpdb->get_var("SELECT * FROM wp_home_tickets WHERE gameid = $gameid ")) { echo 'Ticket already exists for this game.'; goto skip; }
if (!empty($_POST)) { $wpdb->insert( $table_name, $item ); }
skip:
}
?>
I then put this code in my script that fetches and displays the json:
$matchid = $match['id'];
$ticket_url = $wpdb->get_var("SELECT ticketlink FROM wp_home_tickets WHERE gameid = '$matchid' ");
if ($ticket_url) { echo 'Get Tickets'; }
I hope someone does find it of use, i did have to use a wordpress plugin called `Insert PHP Code Snippet' by xyzscripts to be able to snippet the php to a shortcode, but that is not the purpose of this post.
Thanks again for your help.

Laravel 5.2 show saved date in edit form

This is probably a really, really simple issue, but it's got me stumped...
So, I've got an article saved in the database with a form, including a field to save a published date. The data entered in this field is successfully saving in the database, along with the rest of the data.
I'm successfully pulling all the saved data back out into the edit form, EXCEPT the published_date field.
I've tried using the same format as the other fields, eg title, both show below
{!! Form::text('title', null) !!}
{!! Form::input('date', 'first_published', null) !!}
This puts dd/mm/yy in the input box, rather than the saved date. If this value isn't changed, the date is saved in the database as today's date.
I've also tried removing the 'date' attribute
{!! Form::input('first_published', null ) !!}
This results in a totally empty box (and no datepicker), which doesn't overwrite the value in the form if not saved. Better, but still not what I want, as I want to show the saved date, which can be changed if required.
I've also tried echoing the $article->published_date in various ways in this field, but only end up with the same results as those above. I can echo out this data elsewhere in the form no problem though using {!! $article->first_published !!}
The form references the model as so:
{!! Form::model($article, ['method' => 'PATCH', 'url' => 'articles'.'/'. $article->id]) !!}
And the relevant controller functions are
//page containing form to edit article, pulls in existing data
public function edit($id)
{
$article = article::findOrFail($id);
return view('articles.edit', compact('article'));
}
//responsible for updating the article record
public function update($id, Request $request)
{
$article = article::findOrFail($id);
$article->update($request->all());
return redirect('articles');
}
The field is set as a timestamp in the migration, and in the model I have
protected $dates = [
'first_published'
];
So, if anyone can shed any light on how to get the saved data value into the form field as in the other fields, it would be much appreciated! :) I'm pretty new to laravel so apologies if there's some blindingly obvious issue I've missed...
On the offchance anyone else has a similar issue - I've now found the solution, which was embarrassingly simple!
I changed the date field as below:
{!! Form::date('first_published', $article->first_published, ['class' => 'nameofclasshere']) !!}
So that the field's default value is the value pulled from my database (which I was able to access elsewhere in the page as detailed in the question). When I submit the form the date remains as the value from the database, unless I change the form value, in which case it's updated.
Don't know if this is the correct or recommended way to do this (and is still different to how I've done the other fields), but it seems to do the trick!
What I did is replaced the Form::input('date', 'published_at', ... line related segment with the following code section (referring to your Laracast Partials and Forms Reuse tutorial) specifically:
<!-- Published_at Form Text Input -->
<div class="form-group">
{!! Form::label('published_at', 'Publish On:') !!}
{!! Form::date('published_at', (isset($article) && $article->published_at ? $article->published_at : date('Y-m-d')), ['class' => 'form-control']) !!}
</div>
In the above replaced code section (isset($article) && $article->published_at ? $article->published_at : date('Y-m-d')) would check if the Form has given an $article object, so then use its existing published_at date or other wise create date with current time and use it.
Hope this would be helpful to somebody out there.
Clearly this question is closed already, but maybe it can help someone.
I was using a form to both edit and create, so I did the following:
<div class="form-group">
<label class="control-label" for="date_">Proyect Date </label>
<input class="form-control" id="datepicker" name="date" placeholder="DD/MM/AA" value="
#if (isset($proyect->date))
{!!date('d-m-Y', strtotime($proyect->date))!!}
#endif" type="text">

Post comments into a specific status

As the title says, I'm trying to post a comment into a specific user status. So far, I can post comments and save them into firebase but those comments are displayed in all the statuses and of course it's because they are not referenced to that specific user status.
How can I achieve that?
Someone told me that each comment should have a property with the ID of the status or user to be able to make the query. But that's that I dont know how to do.
This is my firebase structure:
Firebase:
-users
-- 444198db-1052-4d8d-a1cd-c7e613fbe7c9
--- Status
--- StatusDate
-comments
-- K-nRDUXT07BllsO7T99
--- comment
--- commentDate
Here is my code to save the comments into the comments node in firebase:
$scope.addComment = function(){
console.log("Adding Comment");
var comment = $scope.comment;
console.log(comment);
var refcomment = new Firebase("https://firebaseurl/comments/");
refcomment.push({
comment: comment,
commentDate: Firebase.ServerValue.TIMESTAMP
});
}
And here the code to show the comments (ng-repeat):
refcomments = new Firebase("https://firebaseurl/comments/");
$scope.comments = $firebaseArray(refcomments);
HTML:
<div ng-controller="ComentariosCtrl">
<div class="input-group">
<input type="text" class="form-control" placeholder="Comment Here..." ng-model="comment">
<span class="input-group-btn">
<button class="btn btn-default" type="button" ng-click="addComment()">Post!</button>
</span>
</div><!-- /input-group -->
<div class="cmt">
<div class="panel" ng-repeat="comentarios in comments">
<hr >
<p>{{comentarios.comment}}</p>
</div>
</div><!--FIN DE COMENTARIOS -->
</div>
Any ideas?
Thanks in advance
It's not clear what 'posting a comment into a specific user status' means exactly but here are a couple of thoughts (and I hope I'm on the right track)
In your example, there's no way to 'relate' the user to the comment. There's about 100 different ways to do it but one flattened structure that could be easily queried for a users comments is:
users
user_id_0001
user_name: "Bill"
user_status: "some status"
status_date: "some status_date"
user_id_0002
user_name: "Ted"
user_status: "some status"
status_date: "some status_date"
comments
comment_id_0001
made_by_user_id: "user_id_0001"
comment: "Hey Ted!"
comment_id_0002
made_by_user_id: "user_id_002"
comment: "Hey Bill! Let's go on a most excellent adventure"
The comments node could then be queried for made_by_user_id = "user_id_0001" which would retrieve all of Bill's comments. Remember in Firebase the flatter the better. Excellent!
Another, less flexible option is to store a users comments within their own users node
users
user_id_0002
user_name: "Ted"
user_status: "some status"
status_date: "some status_date"
comments
comment_id_0001:
comment: "Just call me Neo"
timestamp: "some timestamp"
comment_id_0002:
comment: "I feel like I'm in the Matrix"
timestamp: "some timestamp"
comment_id_0003:
comment: "You trying to tell me.. that I can dodge bullets?"
timestamp: "some timestamp"
Now if you want to retrive all of a users comments, they are just within their own users node at /users/user_id_0002/comments
It really depends on your usage of the data.
The key is to disassociate your data from the node name it's stored in. Using the push() function will generate a unique id can help do that - in the examples above user_id_0001 an comment_id_0001 are generated in this way.

Filter ng-repeat more times

I'm creating an application to manage restaurant orders.
I create the menu from $http so I've this list:
<div class="row vertical" style="background-image: url(/gest/images/etichette/ANTIPASTI.png);border-color: #0CF">
<div class="card piatti col s2" ng-repeat="anti in antis | filter:{tipo:'ANTIPASTI'}">
<div class="card-content"> <span class="card-title truncate red darken-3">{{anti.piatto}}</span> </div>
<div class="card-action"> {{n}}</div>
</div>
</div>
The div with class "row vertical" contain one time starters, then pasta, then beef ecc.
So I use ng-repeat each time, and filter by tipo.
My question is: is there any way to make ng-repeat only one time to show all menu (orderer before by starters, then pasta, beef ecc)?
I have this data (is a restaurant menu):
piatto: name of the the dish
tipo: category of the dish (like pasta, beef, fish, starters ecc)
I would show with only one repeat all the dishes ordered so:
starters, pasta, beef, fish, dessert etc.
And I would create each time a new row
From what I understand you already have all your date on the antis and you just want to filter it by type or do you want to OrderIt by a certain type?
This fiddle for example would order by name, but you can also provide an array with functions to retrieve each type in the way that you like, you can read about it here.
But basically you'd do
anti in antis | orderBy:'+tipo'
or
anti in antis | orderBy: [ function(){}, function(){} ]
EDIT:
As #yarons mentioned you can also chain strings to filter even further. I've updated the Fiddle so now the filter would be anti in antis | orderBy:['+tipo', '+piato']" which indicates that first the tipo would be alphabetically ordered ascending (+ indication) and after that the piato would also be alphabetically ascending.
If you'd want to define a different order than the alphabetical one I think you can use a sort of ENUM for the tipo as in:
var tipoENUM = {};
tipoENUM['ANIPASTI'] = 0;
tipoENUM['PASTA'] = 1;
tipoENUM['PIZZA'] = 2;
tipoENUM['BEEF'] = 3;
tipoENUM['DESERT'] = 4;
So that way you'd avoid using the string for the order, see following fiddle for the example.
EDIT 2:
Ok, so if you receive the data via the HTTP request it's better if you create a order function to help you, check this updated fiddle, like so:
// The enum would be defined as before but:
$scope.orderTipo = function (dish) {
return tipoENUM[dish.tipo];
}
On the HTMl you'll do:
ng-repeat="anti in antis | orderBy:[orderTipo, '+piato']"
Ok your example is perfect but I would repeat each time the "tipo" and then the relative "piato" in a list....something like this:
ANTIPASTI
- bruschetta
- suppli
- fritto
PRIMI
- caqrbonara
- amatriciana
etc.
Is it possible?

Look up data from a diffrent model using Cake

im new to cake (and loving it) but i have hit a problem that i cant seem to find a solution to. Im pretty sure there is an obvious answer to this so my apols in advance if i am asking a stupid question.
Okay, here goes.
I am trying to build a simple message system using Cake PHP version 2.
I have two models at the moment, one handles users (used for loggin in and out) and the other handles messages.
In the messages table i have the following columns:
id | sender_id | recipient_id | subject | body
My MessagesController.php reads as follows:
class MessagesController extends AppController {
public function recent_messages() {
if (empty($this->request->params['requested'])) {
throw new ForbiddenException();
}
return $this->Message->find(
'all'
);
}
}
My View is located in my elements as it actually displayed as a drop down in my navbar. Here is my view:
<?php
$messages = $this->requestAction('/messages/recent_messages');
?>
<?php
foreach ($messages as $message): ?>
<li>
<a href="#">
<div> <strong>Username of sender goes Here</strong></div>
<div><?php echo $message['Message']['subject']; ?></div>
</a>
</li>
<li class="divider"></li>
<?php endforeach; ?>
What i would like to do is to be able to get the actual username of the message sender using the sender_id. Just to clarify the sender_id value is actually the id (primary key) of the user in the users table.
Initially i thought this would be done through setting an association but i cant see how.
If anyone could offer any advice on this i would be most grateful.
I don't understand why you are using $this->requestAction
if your view is recent_messages.ctp you are already calling recentMessages().
Then if you set your relationships you are already retrieving all the data you need
$message['Sender']['username']
contains the information you are looking for. (or $message['User']['username'] it depends on how you wrote your model).
If not read the Manual about setting the relationships.
In brief all you have to do in your Message model is
$belongsTo = array(
'Sender' => array(
'className' => 'User',
'foreignKey' => 'sender_id'
)
)
One further thought.
It seems that you are doing the requestAction from the view. I think it can only be done from the controller and then you pass the result to the view via the $this->set('messages', $message) command.
If I've misinterpreted what you are doing then I'm sorry.

Resources