Load many php-files within controller and situational call them - php

I have another question related to a project of mine. Consider the following scenario.
Scenario
I want to build a Slack App from scratch (to learn something about it)
it will be used for a Slash Command and to send daily updates to a given channel at a given time (via cronjob). So I will most probably provide a config.json and add the modules I want to call when the cronjob triggers the bot.
The bot class builds the bot and also sets up a sendToSlackfunction (does the curl stuff)
In the listen function the bot listens to certain keywords (eg. keyword1) and then execute a certain function. This function gets data from an API. Each keyword he can listen to has its own API-logic.
It would probably be easy to build it with Botkit and node, but I want to stick to PHP and do it on my own.
My questions
How can I load multiple modules (eg. from the /modules directory) in my Slack-App controller (eg. controller.php)?
What is the best way to then "loop" through all the modules I have loaded and if the module says "Hey that is me" (in other words keyword === module.keyword) execute their main function. This main function will get the results from the API and return it back to the controller. The controller will append it to the $outputText variable and at the end use the sendToSlack function to send it to Slack.
Puh, I hope this is it and I did not forget something so far. Do you - hopefully - know what I am talking about? I am happy to answer questions you have and hopefully you can help me.

Related

Seeding Laravel DB from external API

I'm new to Laravel. Maybe my questions are a little bit silly... Sorry...
The goal: There are some API resources and I need to take some selective data from them (It will be needed to make extra API queries from data which I already got before to get full sets of required values) and fill my DB tables with it (some as one to many, some as many to many).
The problem: What Laravel tools do I need to use to reach this goal? Is it factory, seeder or somewhat else? In addition I don't understand where I have to write the code for getting data from an external API and where (in terminal manually?) I have to initiate my DB tables filling.
Maybe someone could at least advise what to learn in the Laravel official documentation at first or some helpful reference to some article from which I will be clear how this process may be implemented in Laravel. I mean the tools' set and order to use them. Not the finished code implementation of course.
I will be grateful for any help. Thanks. Sorry for my non native English.
Well, there are multiple ways of achieving what you want:
One is to create a command where you are going to write code to fetch this data (using curl or any similar way). And then you manually run the command when you want with whatever arguments you want.
Other one is to use the previous step and schedule it to run in a desired time with desired arguments.
Other possible way is, if the external API can send data to a specific URL when some action occurs in that system, then you can create a normal Route and the API should point to this Route in your Laravel. It will be specific and only work for this API.
Other one is to fetch data based on an event. Let's say that, if a user register, when this is successful, you are going to fetch User info from an external API using their email (let's say you want to get a profile picture from an API and the only way to get the user picture is sending the user's email). You can do so using Events.
There are more ways, but if you don't give too much context, then this is what I can share with you !

Codeigniter - find out if class was called directly

I am attempting to create a controller that can detect if it is called from another controller in the application.
If it called directly via the URL, however, I need to know so I can perform some other actions.
i.e.
cheese/modulename calling potato/modulename is different to someone accessing site/cheese/modulename via URL - and I need to be able to pick up on this and act accordingly.
I am aware of:
$this->router->class
but it will not work as I may have the same named class in another module (HMVC pattern as an FYI) that may want to call this controller (cheese/modulename calling potato/modulename as an example would return 'modulename' - so I can't use that as a check to see if it was called by itself.)
I basically need a check for:
controller was called via another controller = true / false
can anyone tell me how (or if I am being thick!)
I am doing this in the __construct() just in case your solution will have a problem with that (can't see why but you never know!)
EDIT
Thank you to Mohammad Walid for his answer.
For clarity the structure is
CLIENTS
MODELS
CONTROLLERS
- Client
- Api
VIEWS
JOBS
MODELS
CONTROLLERS
- Jobs
- Api
VIEWS
I will be calling the API from Client - but may also call it from another API (possibly) That may be
In another Module
For Example the CLIENTS Api might get called from the JOBS Api Controller (I have no intention of doing this at present but it may be a possibility under different scenarios I haven't forseen and want to make it future-proof so I don't have a massive refactoring job in the future.)
You can try this:
function is_called_via_url($controller_object){
return $this->uri->segment(1) === get_class($controller_object);
}
and in your controller:
if(is_called_via_url($this)){
//do something
}
I'm not quite sure if passing $this as an argument in the constructor will work, but it worth try.
Reference and a hint from MonkeyZeus's comment.
From the comments there seems to be no way to do this without using debug_backtrace($options, $limit)
However the work-around I have ended up doing is to add a 'flag' within the authorisation module (which is called before all controllers)
The flag defaults to false.
If a controller from within my application calls the API page I turn this flag to true (is_application = true - I am currently just manually pasting this into the __construct of any controllers in my application that need to talk to my API)
I can then just do a simple
if(!is_application){
//this was called directly from the URL not from within the application
}
from within the API controller.
Hopefully this will be helpful for others who are attempting this sort of thing and once again thank you to the people who took the time to comment / answer.

iPhone requests to php

I am working on the php side and my friend is working on the iPhone side. We are creating an app with friends and groups. I was wondering if it was better to use separate files for each task such as create group, delete group, add friend, remove friend or is it better to use one update class that calls the necessary function.
I can see two methods and personally I'd pick the first one because it allows me to be the most flexible, but of course the decision is yours to make.
Get/Post to one file
You have one connector file that your objective-c application posts on, and then that connector file contacts your other files.
An example of this flow might looks like:
iPhone (POST request) {'method':'addGroup', 'groupName':'My Group'} -> connector.php
Then connector.php will contact groups.php and run the method addGroup.
For addGroup, you could have it use GET instead, such as connector.php?method=addGroup&addGroup=My%20Group.
Of course, authentication should always be with POST, so you'll have to use POST for that and for more complex or larger amounts of data.
Get/Post to multiple files
This could be a viable option too. In your document root, you would simply have all the file exposed such as:
/htdocs
/addGroup.php
/removeGroup.php
/editGroup.php
/login.php
/logout.php
Then your iPhone app will contact each one of these end points.
In conclusion I'd prefer the first method simply because you are left with only one end point, this allow you to control which methods are available for the user to run.
So first thing first, the organization you want is really dependent on the organization you need. Everyone organizes things based on what they are comfortable with, so the question itself is a bit subjective. (Not to mention there are several ways you can go about this, again, all depending on your organization.)
One method is to put all your CRUD (CReate - Update - Delete) operations for individual domain objects (friends and groups in this case) in single files. So in this case you might have files called create.php, update.php, delete.php and they might look something like:
<?php
class Update
{
public function updateUser()
{
//code to update a user
}
public function updateGroup() { ... }
}
?>
Your other classes would look similar.
You would then create a mechanism for deciding which type of object to run the update operation on, likely through parameters passed in your GET or POST variables.
Another way (and the method I would lean towards), would be to add your operations directly in with the domain objects. Like so:
<?php
class User
{
public function updateUser()
{
//update the user
}
public function deleteUser()
{
//delete the user
}
....
}
?>
Hope that helps clarify some. Again, this is a fairly subjective question, so it really depends on your coding and organizational preferences.

Symfony2 - Current User Access to Route

I have access_control setup in the security configuration of my Symfony app so, clearly, the application can detect if the current user has access for the current request (that works just fine). What I want to be able to is have the app figure out if the current user would have access to another request (eg. a different path or method) from a Controller action.
What is the proper way to do this in Symfony? I can hack together going through and accessing the FirewallContext of the current request and looking for the proper listener with the proper AccessMap but this is ugly and I fear that it will break easily. Any suggestions?
This question has gone unanswered for almost a week now so I've found a decent workaround solution in the meantime, if anyone finds this and wants to do something similar.
First of all, I pulled the functionality from AccessListener::handle(GetResponseEvent) out into a new class/method Authorization::checkAccess(Request) which takes a Request object instead of a GetResponseEvent.
Next (and the necessity of this depends on whether or not checkAccess differs from the way handle handles requests), I created a separate class to override AccessListener and use Authorization::checkAccess(Request) to do the checking (and swapped it out in the configuration by setting the security.access_listener.class parameter)
Next, setup a service in the configuration to construct an Authorization object with all of the parameters that are injected into the AccessListener.
Finally, in order to check a particular request, I use this slice of code in the controller:
$check = $this->getRequest()->duplicate();
$check->server->set('REQUEST_URI', $requestUri);
$check->setMethod('GET');
$this->get('my_access_control_service')->checkAccess($check);
I hope this helps someone out there...

Cakephp cron job to call a controller's action

I started to use CakePHP (1.2) a few months ago to add small features to the company's application and I'm not too familiar with it.
We test locally then on a development server before merging to a production server.
I want a controller action to be called every hour with what I assumed to be the best way to do this through my researches, a cron job.
Attempt 1
After reading these,
http://bakery.cakephp.org/articles/mathew_attlee/2006/12/05/calling-controller-actions-from-cron-and-the-command-line
http://book.cakephp.org/1.2/en/view/110/Creating-Shells-Tasks
I could implement something without errors, but the action is not executed.
Based on these examples, I added a file named cron_dispatcher.php in my app directory (not app/webroot) and then did this command from the app dir
php cron_dispatcher.php /controller/action/param
Still nothing happened but it works perfect when I call it through the url.
Attempt 2
I tried creating a shell (email.php) that would call the action in /app/vendors/shells/.
<?php
class EmailShell extends Shell {
public function main() {
$this->out('Test');
}
}
?>
This successfully outputs Test in the console using
cake email main
but then I cannot find how to call the controller's action. I have tried
$this->requestAction('/controller/action');
I have also tried to make the call from a different function than the main in the shell.
I have tried to include the controller in the $uses variable as I would with a model but that didn't work (and it doesn't make sense I think)
I don't think creating a task is the solution either as I don't want to duplicate the sendEmails function hence why I'm looking for a way to just call the controller's action from a shell or whatever!
There is probably some theory I'm missing, thanks
Solution
I moved some methods from the controller to a model and I was able to call them from a shell.
App::import('Component', 'Email');
class SendMemosShell extends Shell {
var $uses = array(
'Memo',
);
public function main() {
}
public function sendEmails () {
$this->Email =& new EmailComponent(null);
$memoList = $this->Memo->getMemos();
//...
}
}
This link helped
http://book.cakephp.org/2.0/en/console-and-shells/cron-jobs.html
edit : clarified some of the information and added the solution
It is a quite common issue actually, ran into it also.
A controller is deciding how to handle a request and starting that task. In this case there is no need for a controller since you have a shell task, the task is already clear.
Knowing that, it does not make sense to call a controller method.
So rethink your options, and yes this is a quite difficult one. For example you might decide that sending the e-mail is a business logic step so it should be in the model. Another option is to separate it totally (that's what we like most).
In that case you will have to create a queue where you put in all e-mails to send. That is a good design since you then know the amount of logic in the controller goes down and it is separated. That way you get an e-mail service.
For example you could ask the service to send a "new user" mail. Then you add the User object to it and it should handle itself. That way you can even scale since your service could be for example outsourced, you could expand multiple servers on the service etc.
Edit:
Good questions.
Steps to take:
Centralize the "sending e-mail" process first. So choose one location where to put it. The you can decide: Add to send e-mail to a queue or call the service directly. For example you could add shell task for sending the e-mails.
Call the shell: Now you have the problem to call the shell. In general you don't want to. Why not? Because a shell (a task) could run for a long time. So that's why we use queues in between. So you can ask the queue or let the queue message you that something is done. For example think about a mail server which is down. You have to retry etc. That should not be in a web request because the user is waiting for response.
Third step is to call the shell from your cron, now that's easy since you are already on the command line so you could use standard calls.
Anyhow, there are options to do a direct call from a controller but you should not. This post gives some very interesting insights:
CakePHP: Run shell job from controller
Edit 31/08/'13: See the events system of CakePHP also for some examples: http://book.cakephp.org/2.0/en/core-libraries/events.html
Depending on what needs to be done, I often keep these methods in my controller actions. At the top of the action I check $_SERVER['REMOTE_ADDR'] == $_SERVER['SERVER_ADDR'] to ensure only the website can call the action. Then in cron I would curl or wget this address.
It has its benefits - easier to run locally during development (just enter the url in your browser), plus there are some differences between running cli version of php and apache version, as well as the request variables (eg. cake can't get the website domain/address through cli like you can running as apache module, so absolute links to the website using html helper don't work).

Categories