I’m looking at different mail services for using with my Codeigniter projects. Amongs them: Mandrill, Mailgun, Postmarkapp etc.
In most cases, there is already one or more Codeigniter libraries available but If I want to build on them, making simpler methods that are more suited to my projects and CMS workflow for instance, what’s the best way to approach without having to write the whole thing from scratch?
Is it best to create a new class that extends the existing CI library? and then include those two files? /libraries/mailgun & /libraries/my_mailgun.php
I'm using this method.
I put the put the external libary in /application/third_party, after I create a class in /application/libraries with name my_{project name}.
Inside the my_{project name} I put a require_once as the follow code
require_once APPPATH."/third_party/projectname/main.php";
class Algumnome extends Project {
public function __construct($arg1 = 'defaultValueToProject', $arg2 = 'defaultValueToProject'){
parent::__construct($arg1, $arg2);
}
}
I my controller I call the lib like:
$this->load->library('algumnome');
$this->algumnome->method();
You definatly answered your own question here.
Is it best to create a new class that extends the existing CI library? and then include those two files? /libraries/mailgun & /libraries/my_mailgun.php?
Yes, is the correct answer, this way you can Add new functionality to an existing library without having to reinvent 90% of the wheel.
class My_lib extends stock_lib
{
function newMethod1()
{
}
function newMethod2()
{
}
function etc()
{
}
}
As you already mentioned this will allow you to use your new functions as well as the existing functions to the parent class.
so, i should up-vote you for answering your own quesiton, and this answer is just a re-iteration of you answer.
Related
I am developing a package for Laravel 5, and now I need to benefit from dependency injection to have a more scalable and relaible application, I don't know which approach is the best to take and why, this is a piece of my code and I need to injected the Lang class dependency
class MyController extends \App\Http\Controllers\Controller
{
public $text;
public $lang;
public function __construct()
{
// Some codes here
}
public function myFunction(){
$this->text = \Lang::get('package::all.text1');
}
}
In this link http://laravel.com/docs/4.2/ioc 2 approaches are suggested, Basic Usage and Automatic Resolution based on my understanding from the link
taking the first approach I need to add
App::bind('lang', function($app)
{
return new \Lang();
});
to the register part of application and then in the function I'll have something
like this :
public function myFunction()
{
$lang = \App::make('lang');
$this->text = $lang::get('package::all.text1');
}
The other way is to modify the constructor like
public function __construct(Lang $lang)
{
$this->lang = $lang;
}
And then instantiate object from Class like
$myController = App::make('MyController');
Which way is the better way to take for, considering that this class is a Controller and it will be called in the routes file, or please correct me if my understanding from the link is not right. please also inform me why you suggest any of those approaches.
It should be noted that using local IoC resolution ($app->make() stylee) is not much better than using the facades directly (Lang::get() stylee) - you're still very much relying on Laravel's specific classes without really making your code explicitly state that it needs these exact classes. So the general advice is to, as much as possible, code to an interface if you want your code to be as portable as possible.
Of course there are a couple of big downsides to this currently in PHP development:
These interfaces are not generally defined (except the PSR-3 LoggerInterface interface) so you still have to rely on a particular instance of the interface (in this case, Laravel's).
If you decide to make your own generic interface (or the FIG eventually creates some of these), the classes that Laravel provides for translation (for example) don't implement it anyway, so you then need to subclass the existing ones just to make it look like it implements your own interface. But hey, that's the current best practice, so I guess if you wanna be using the current best practices, code to an interface, and don't worry for the time being that the interface you're coding to is Laravel-specific.
But anyway, here are my thoughts on your specific question. First off I should say that I haven't actually used Laravel 5 yet (just the 4s), but I have generally followed its development.
If the class I am coding will use a given dependency quite a lot or as a core part of how the class works I will use constructor dependency injection. Examples here are the Request or some Repository class in a controller, or a business logic class in a console command class.
If what I need I only need for a specific purpose (maybe redirecting from a controller and needing to generate a URI) I will resolve a local version from the IoC container ($this->app->make()) and then use that. If I were using Laravel 5 and the method was called by Laravel directly (e.g. a controller's action method) I may use method injection for this, I'm not 100% sure.
As a final note, the general advice is that if your constructor method signatures get too big due to a lot of dependencies:
It's time to have a look at if your code relies too much on external dependencies. Maybe some of the functionality of your class can be extracted to its own class that splits the dependencies between the two.
You should consider using setter methods rather than constructor injection - so instead of accepting a Request object, you have a $class->setRequest() method. The downside of doing this is that you need to tell Laravel's IoC container how to instantiate your object (i.e. that these setters must be called). It's not that big a deal but something worth noting.
Relevant links:
Laravel 5's IoC article
Laravel 5's Controller injection advice
Am having problems understanding where classes should be kept in CI. I am building an application that describes / markets mobile phones.
I would like for all of my functions (i.e. getphone, getdetails etc.) to reside in one class called Mobile - I understand that this file should be called Mobile.php and reside in the controllers folder.
Can I then have multiple functions inside Mobile.php? E.g.
public function getphone() {
xxx
xx
xx
}
public function getdetails() {
xxx
xx
xx
}
Or do I need to put each function in its own class?
I'd really appreciate looking at some sample code that works. I've been going through the documentation and google for a few hours, and tried all sorts of variations in the URL to find a test class, but without much luck! I've even messed around with the routes and .htaccess...
All I am trying to achieve is the following:
http:///model/HTC-Desire/ to be re-routed to a function that accepts HTC-Desire as a parameter (as I need it for a DB lookup). The default controller works fine, but can't get anything to work thereafter.
Any ideas?
Thanks
Actually it works like this:
Controllers and Models go to their perspective folders as you know it
If you want to create functions that are not methods of an object, you must create a helper file. More info here :
http://codeigniter.com/user_guide/general/helpers.html
Now if you want to create your own datatypes (classes that don't extend Models and Controllers), you add them to the library folder. So if let's say you want to create a class "Car" you create this file:
class Car{
function __construct(){}
}
and save it in the libraries folder as car.php
To create an instance of the Car class you must do the following:
$this->load->library('car');
$my_car = new Car();
More information on libraries here:
http://codeigniter.com/user_guide/general/creating_libraries.html
Yes, you can have as many functions in a controller class as you'd like. They are accessible via the url /class/function.
You can catch parameters in the class functions, though it's not advisable.
class Mobile extends CI_Controller{
public function getPhone($phoneModel=''){
echo $phoneModel;
//echo $this->input->post('phoneModel');
}
}
http://site.com/mobile/getPhone/HTC-Rad theoretically would echo out "HTC-Rad". HOWEVER, special characters are not welcome in URL's in CI by default, so in this example you may be met with a 'Disallowed URI characters" error instead. You'd be better off passing the phone model (or any other parameters) via $_POST to the controller.
Classes can exist both as Controllers and Models, as CodeIgniter implements the MVC pattern. I recommend reading more about that to understand how your classes/functions/etc. can best be organized.
Off the top of my head, Pyro CMS is an application built with CodeIgniter and the source code is freely available. I'm sure there are others.
I think it's best you handle it from one perspective, that is; create a utility class with all your functions in it.
The answer to the question of where to put/place the class file is the "libraries" folder.
This is clearly stated in the documentation. Place your class in the libraries folder.
When we use the term “Libraries” we are normally referring to the
classes that are located in the libraries directory and described in
the Class Reference of this user guide.
You can read more on creating and using libraries Creating Libraries — CodeIgniter 3.1.10 documentation
After placing the newly created class in the libraries folder, to use just simply load the library within your controller as shown below:
$this->load->library('yourphpclassname');
If you wish to receive several arguments within you constructor you have to modify it to receive an argument which would be an array and you loading/initialization would then be slightly different as shown below:
$params = array('type' => 'large', 'color' => 'red');
$this->load->library('yourphpclassname', $params);
Then, to access any of the functions within the class simply do that as shown below:
$this->yourphpclassname->some_method();
I hope this answers your question if you have further question do leave a comment and I would do well to respond to them.
In Rails, you can organize controllers into folders and keep your structure nice with namespacing. I'm looking for a similar organizational structure in Symfony 1.4.
I was thinking of organizing multiple actions.class.php files in an actions folder, but all I came across was using independent action files, one for each action... like this:
# fooAction.class.php
class fooAction extends sfActions {
public function executeFoo() {
echo 'foo!';
}
}
But I'd have to develop a whole new routing system in order to fit multiple actions into that file, which is... silly.
Really I'm just looking to make Symfony into Rails, (again, silly, but I'm stuck with Symfony for this project) so I'm wondering if there's a better way....?
Thanks.
An alternative action syntax is
available to dispatch the actions in
separate files, one file per action.
In this case, each action class
extends sfAction (instead of
sfActions) and is named
actionNameAction. The actual action
method is simply named execute.
class indexAction extends sfAction
{
public function execute($request)
{
// ...
}
}
A Gentle Introduction to symfony - chapter 06: Inside the controller layer, subsection Alternative Action Class Syntax
I'm updating an php web application that is becoming multilingual, based on the Zend MVC framework, and I'm trying to figure out the best approach to passing the translation object to different classes/layers.
Most of my translation is done at the View level, but there are a few cases where I need to return status messages from custom libraries.
I could just create a property for the library and set the translator, but I'm wondering if there is a better way to integrate a translator object into an existing application?
Hold the users lanaguage in a Memento, and pass that through the program logic, when you need to do that translation use it identify the language.
If using Zend_Translate, it's best option to use register.
Zend_Registry::set('Zend_Translate', $translate);
This way all classes can find it automatically (Zend_Form, Zend_Validate, ...)
You could always instantiate the translator in the bootstrap.php so it is available to all classes as a global. That's how I'd do it since you probably need to use it everywhere. It isn't elegant, but it keeps you from having to add code wherever a class needs to throw an exception or return an error message.
If you don't have that many controllers setup can you not extend the base controller and instantiate the translator there? It should be available for use throughout the system then.
Something like this to extend:
<?php
class BaseController extends Zend_Controller_Action
{
public function init()
{
//setup translation object
}
}
?>
You might want to consider to use a dependency injector container, where the translator is an entry that you pass to the objects you need, without manually constructing the object. That way you can easily test and make more high quality (and testable) code
See other question here
How to use dependency injection in Zend Framework?
or this article about plugging ZF 2 DI into ZF1
http://adam.lundrigan.ca/2011/06/using-zenddi-in-zf1/
I have a user class with static methods getById and getByUsername
I have the class in the application/libraries folder
How do I call the classes from a controller?
Theory 1:
$this->user = new User();
$this->user::getById;
Theory 2:
$user = new User();
$user::getById;
or is there a clean way of doing it much like how Kohana helpers do it; much like:
text::random();
here's what I am trying to accompplish:
I want to call a static mehthod in the user library from my controller
In PHP you usually include the file (User.php) and the static methods are ready
User:getById
but then how would I do the same thing in an MVC framework?
shall I do an include too?
Like include ('User.php');?
User::getById();
and
User::getByUserName();
Edit: In response to your question edit, generally frameworks have an auto-loading mechanism that will find and load a class file for you once you reference that class. So when you type User::getById(), the PHP interpreter will see that it needs to load the User class (if it hasn't been loaded already), and run the autoloading procedure to find the correct code to include.
I've never used Kohana, but I would be quite surprised if it didn't use some form of autoloading. If it does not, then yes, a simple include('User.php') will be enough to make the static method calls to User work.
The confusing thing is Kohana's convention of writing "helper" classes with lowercase names.
Your user php file will probably all ready be loaded if your using it as a model, so you can use zombat's suggests of User::getById();.
I don't like to follow their naming convensions for helpers or libraries and instead do:
require_once(Kohana::find_file('libraries', 'user_utils', TRUE, 'php'));