What is the "arg" field value that is sent on woocommerce_add_to_cart webhook? - json

I would like to know whether an addition of a product to a cart occurred on woocommerce. On the documentation it says that an application should consume a webhook that notifies about a woocommerce_add_to_cart action.
So I implemented it and gladly got a message saying it happened a short while after such an event occurred.
Here's an example JSON I got from woocommerce:
{"action":"woocommerce_add_to_cart","arg":"fe9fc289c3ff0af142b6d3bead98a923"}
However since many visitors of a woocommerce website may have their own cart, and many products, I would like to know if there's a way to decode the arg field so that it will provide a unique product that was added to a specific cart.
In case I am using the wrong method in order to learn about an addition to a cart, I would be happy to learn which one may be better for me.

The 'arg' value is the cart item key that is passed through woocommerce_add_to_cart action hook as an argument, and that is returned on WC_Cart add_to_cart() method on line 1120:
do_action( 'woocommerce_add_to_cart', $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data );
return $cart_item_key; // <========= HERE
That cart item key allows you for example to get the cart item using WC_Cart get_cart_item() method and retrieve the cart item data:
$cart_item = WC()->cart->get_cart_item( $cart_item_key );

Related

What is the best practice to design REST URI for the following use case

A user can singup in an application
/users
GET /id get userDetails
POST saveUserDetails
A admin can create events for a user to register
/events
POST saveEvent
PUT /{event-id} for updating event
DELETE /{event-id} deleting an event
Now, the question is where would you place user to event registration uri?
will it be
/events/{event-id}/register
or
/users/{user-id}/events?event-id=xxx
and I also want to get list of the events to which the user has registered
Please help me with better API design
There's no right answers here, so I'll just throw in the hat the patterns that I would probably use:
POST /user - register a new user
GET /user/:id - Get user info
PUT /user/:id - Update user info
POST /event - create an event
PUT /event/:id - Update an event
GET /event/:id - Get event details
DELETE /event/:id - Delete event
GET /event/:id/attendees - Get list of attendees
POST /event/:id/attendees - Add user to list of attendees
GET /user/:id/event - Get list of events that user is attendee of
The main goal is to register to an event. Then you should start with /events
This is why /events/{event-id}/register looks fine to me.
There are various ways by which you can achieve this but what I see as the best practice is that you should be able to understand from the URL itself that what you're trying to achieve.
For example,
Admin wants to create an event:
POST: {basePath}/a/events or {basePath}/admin/events
a | admin: defines that this action is being performed by an Admin
events: defines that operation is being performed on events entity
Now User wants to register for the event, hence
POST: {basePath}/u/events/{eventId} or {basePath}/user/events/{eventId}
u | user: defines that this action is being performed by the User
events: defines that operation is being performed on events entity. Which can be multiple entities hence adding eventId in the path variable to define which you need to register.
now in the above example, I am assuming you can get the User details in the request
or capture it from the session but if that is not the case you want to follow then you might need to use below example (assuming path variable is the only option for you to get the User context)
POST: {basePath}/u/{Id}/events/{eventId} or {basePath}/users/{userId}/events/{eventId}
You can read more here about naming guide if you like.

Getting the value of a particular cell with AJAX

My goal is very simple and I would guess it is a very common goal among web developers.
I am creating a Rails (5.1) application, and I simply want to use AJAX to get the value of a specific cell in a specific row of a specific table in my database (later I am going to use that value to highlight some text on the current page in the user's browser).
I have not been able to find any documentation online explaining how to do this. As I said, it seems like a basic task to ask of jquery and ajax, so I'm confused as to why I'm having so much trouble figuring it out.
For concreteness, say I have a table called 'animals', and I want to get the value of the column 'species' for the animal with 'id' = 99.
How can I construct an AJAX call to query the database for the value of 'species' for the 'animal' with 'id' = 99 .
Though some DBs provide a REST API, what we commonly do is define a route in the app to pull and return data from the DB.
So:
Add a route
Add a controller/action for that route
In that action, fetch the data from the DB and render it in your preferred format
On the client-side, make the AJAX call to that controller/action and do something with the response.

Cakephp 3.0 - Validating Input against data in another model

I'm a pretty new to Cakephp 3.0 and I'm quite stuck on data validation, or rather Application Rules.
I have a simple user registration form to create a new user in the table 'users'. In the user registration form, there is a field for "ticket_number" where the user has to enter a ticket number which must exist in the table tickets.ticket_number, and also tickets.registration_status must be false (that ticket had not had a user registered with it yet).
My tables look like this (simplified:)
users:
id | username | password
tickets:
id | ticket_number | user_id | registration_status
In my users model, I have defined (user can have many tickets):
$this->hasMany('Tickets', [
'foreignKey' => 'user_id'
]);
In my Tickets model, I have defined (a ticket belongs to a user):
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
In the users model, I added a rule to attempt to check whether the entered ticket_number exists in the tickets.ticket_number column:
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->isUnique(['username']));
$rules->add($rules->isUnique(['email']));
$rules->add($rules->existsIn
(['ticket_number'], 'Tickets.ticket_number'));
return $rules;
}
This gives me the error:
Error: Call to a member function primaryKey() on a non-object
I'm very stuck here. Can anyone advise on the right approach implementing this check? And then, how to also implement the check to see whether the associated registration_status is 0 (that ticket has not been registered yet).
Thanks in advance for any advice!
--D.
The existsIn rule will not solve your problem, as it will not take your additional condition into account (registration-status).
You will need to provide a custom rule to accomplish the problem you described.
Regarding your update: The rule will return true - so passing the rule, if your tables are not setup correctly or it cannot find the field you are referencing or your field is nullable, check the source here: http://api.cakephp.org/3.0/source-class-Cake.ORM.Rule.ExistsIn.html#74-91
OK, after considerable tinkering, I solved the first issue (On the user add form, the user must enter a ticket number which must exist in the table tickets.ticket_number.)
The only way I could get this to work using an existsIn rule in the UsersTable model, was to declare the ticket_number field as the primary key in the initialize method of the TicketsTable model:
$this->primaryKey('ticket_number');
Then the associations and existsIn rule in the UsersTable model worked. However, this isn't good as I don't want the primary key in tickets permanently set to ticket_number. It also doesn't solve my second problem (checking tickets.registration_status is false.)
So I took a different approach and instead used $this->loadModel('Tickets'); in the add method of my users controller. Then, I could easily perform the required checks:
//Look for this particular ticket
$ticketCount = $this->Tickets->find()->where(['Tickets.ticket_number' => $ticket_number])->count();
$this->set(compact('ticketCount'));
$this->set('_serialize', ['ticketCount']);
//If the ticket isn't found, then return with the Flash error
if (!$ticketCount > 0) {
$this->Flash->error(__('Sorry, but a Ticket with this number could not be found. Please, try again.'));
return;
} //otherwise move on...
I then similarly query the registration status of the ticket, and flash a different error back if it is already registered.
After the checks are passed, it goes on to the normal Add User checks and saving.
While this solution isn't as elegant as what I was hoping to do in the Users model with a custom association and rule, it works.
I'm also not convinced it can't be done in the model with a rule. But for now, this solution works.
Anyway thanks hmic for a response.
DBZ

Office 365 Rest API - Changing message Id

Is there any scenario in which the Id field on a message could change?
We received a message at today (Thu, 19 Feb 2015 10:29:48 GMT +00:00) with an ID ending in 'MT80AAA='. However when trying to retrieve message details at a later time I get a 404 error with the message:
{ "error" : { "code": "ErrorItemNotFound", "message" : "The specified object was not found in the store." } }
When I do another request to get all messages from that inbox the same message appears however it has another ID ending in 'TwDlAAA='.
Both the message ID and the Attachment ID have been changed at some point from the first time receiving the message and now.
Is this a common occurrence? What could cause this? Or is it a bug?
It's not a bug, it's definitely a common occurrence with Exchange. Entry ID's aren't static, and can change in a number of scenarios. Common ones are moving the item (which is essentially a copy and delete operation, copy gets a new ID since it's a new item), or mailbox move (which may be applicable to your case).
Typically I would advise a strategy of optimistically storing the ID and using it first, since it will usually work. Then I'd recommend storing the record key and search key as a backup, so you could try searching for the item in the event the Id no longer works. However, the REST API doesn't expose these fields! So you'd have to make do with searching for the item based on whatever fields are important to you, which isn't ideal. I'll provide this feedback to our developers.

Laravel Eloquent how to limit access to logged in user only

I have a small app where users create things that are assigned to them.
There are multiple users but all the things are in the same table.
I show the things belonging to a user by retrieving all the things with that user's id but nothing would prevent a user to see another user's things by manually typing the thing's ID in the URL.
Also when a user wants to create a new thing, I have a validation rule set to unique but obviously if someone else has a thing with the same name, that's not going to work.
Is there a way in my Eloquent Model to specify that all interactions should only be allowed for things belonging to the logged in user?
This would mean that when a user tries to go to /thing/edit and that he doesn't own that thing he would get an error message.
The best way to do this would be to check that a "thing" belongs to a user in the controller for the "thing".
For example, in the controller, you could do this:
// Assumes that the controller receives $thing_id from the route.
$thing = Things::find($thing_id); // Or how ever you retrieve the requested thing.
// Assumes that you have a 'user_id' column in your "things" table.
if( $thing->user_id == Auth::user()->id ) {
//Thing belongs to the user, display thing.
} else {
// Thing does not belong to the current user, display error.
}
The same could also be accomplished using relational tables.
// Get the thing based on current user, and a thing id
// from somewhere, possibly passed through route.
// This assumes that the controller receives $thing_id from the route.
$thing = Users::find(Auth::user()->id)->things()->where('id', '=', $thing_id)->first();
if( $thing ) {
// Display Thing
} else {
// Display access denied error.
}
The 3rd Option:
// Same as the second option, but with firstOrFail().
$thing = Users::find(Auth::user()->id)->things()->where('id', '=', $thing_id)->firstOrFail();
// No if statement is needed, as the app will throw a 404 error
// (or exception if errors are on)
Correct me if I am wrong, I am still a novice with laravel myself. But I believe this is what you are looking to do. I can't help all that much more without seeing the code for your "thing", the "thing" route, or the "thing" controller or how your "thing" model is setup using eloquent (if you use eloquent).
I think the functionality you're looking for can be achieved using Authority (this package is based off of the rails CanCan gem by Ryan Bates): https://github.com/machuga/authority-l4.
First, you'll need to define your authority rules (see the examples in the docs) and then you can add filters to specific routes that have an id in them (edit, show, destroy) and inside the filter you can check your authority permissions to determine if the current user should be able to access the resource in question.