How to properly add Red Bean PHP into my project - php

I'm not very experienced with php projects structure, I found this awesome and simple tutorial: https://arjunphp.com/creating-restful-api-slim-framework/ how to create simple slim rest app.
This is actually PHP SLIM's official project structure, my question is what is best and proper way to add and use RedBean php ORM, I dont want on every route to include something like this
use \RedBeanPHP\R as R;
R::setup( 'mysql:host=localhost;dbname=mydatabase', 'myusername', 'mypassword)
and then
$book = R::load( 'book', $id );
And then use ReadBean for my db stuff. Im wondering how to include RedBeans into project and then just use it where i need it. This is my project structure https://github.com/iarjunphp/creating-restful-api-slim-framework3.
Note: i added red beans via composer like its described here https://github.com/gabordemooij/redbean

You can put the code for setting up your libraries in any file that is going to be included on each request, so assuming you're using slim/slim-skeleton, src/dependencies.php is probably the place you want to add these two lines:
use \RedBeanPHP\R as R;
R::setup( 'mysql:host=localhost;dbname=njux_db', 'root', '');
Then you can use ReadBeans in your route callbacks but you also need to add the use \RedBeanPHP\R as R; statement to your src/routes.php as well (or any file that is going to use this class)

If you use a MVC framework (which I recommend) like codeigniter it's pretty easy.
You only have to copy your rb.php to the application/third_party folder.
Then create a file called application/libraries/rb.php containing a code like this one.
<?php
class Rb {
function __construct() {
include(APPPATH.'/config/database.php');
include(APPPATH.'/third_party/rb.php');
$host = $db[$active_group]['hostname'];
$user = $db[$active_group]['username'];
$pass = $db[$active_group]['password'];
$db = $db[$active_group]['database'];
R::setup("mysql:host=$host;dbname=$db", $user, $pass);
}
}
?>
...and vĂ´ila. RedBean will read your database configuration from CodeIgniter's standard file application/config/database.php and you will be able to use any R:: command from anywhere in your code. No includes, not additional code required :-)

Related

Can I use the Blade templating engine outside of Laravel?

i'm want to creating a design pattern and use the "Blade templating engine".
Can I use the Blade templating engine outside of Laravel and use it in my new pattern ?
For the record:
I tested many libraries to run blade outside Laravel (that i don't use) and most are poor hacks of the original library that simply copied and pasted the code and removed some dependencies yet it retains a lot of dependencies of Laravel.
So I created (for a project) an alternative for blade that its free (MIT license, i.e. close source/private code is OK) in a single file and without a single dependency of an external library. You could download the class and start using it, or you could install via composer.
https://github.com/EFTEC/BladeOne
https://packagist.org/packages/eftec/bladeone
It's 100% compatible without the Laravel's own features (extensions).
How it works:
<?php
include "lib/BladeOne/BladeOne.php";
use eftec\bladeone;
$views = __DIR__ . '/views'; // folder where is located the templates
$compiledFolder = __DIR__ . '/compiled';
$blade=new bladeone\BladeOne($views,$compiledFolder);
echo $blade->run("Test.hello", ["name" => "hola mundo"]);
?>
Another alternative is to use twig but I tested it and I don't like it. I like the syntax of Laravel that its close to ASP.NET MVC Razor.
Edit: To this date (July 2018), it's practically the only template system that supports the new features of Blade 5.6 without Laravel. ;-)
You certainly can, there are lots of standalone blade options on packagist, as long as you are comfortable with composer then there should be no issue, this one looks pretty interesting due to having a really high percentage of stars compared to downloads.
Be warned though i have not tried it myself, like you i was looking for a standalone option for my own project and came across it, i will be giving it a real good workout though at sometime in the near future,
Matt Stauffer has created a whole repository showing you how you can use various Illuminate components directly outside of Laravel. I would recommend following his example and looking at his source code.
https://github.com/mattstauffer/Torch
Here is the index.php of using Laravel Views outside of Laravel
https://github.com/mattstauffer/Torch/blob/master/components/view/index.php
You can write a custom wrapper around it so that you can call it like Laravel
use Illuminate\Container\Container;
use Illuminate\Events\Dispatcher;
use Illuminate\Filesystem\Filesystem;
use Illuminate\View\Compilers\BladeCompiler;
use Illuminate\View\Engines\CompilerEngine;
use Illuminate\View\Engines\EngineResolver;
use Illuminate\View\Engines\PhpEngine;
use Illuminate\View\Factory;
use Illuminate\View\FileViewFinder;
function view($viewName, $templateData)
{
// Configuration
// Note that you can set several directories where your templates are located
$pathsToTemplates = [__DIR__ . '/templates'];
$pathToCompiledTemplates = __DIR__ . '/compiled';
// Dependencies
$filesystem = new Filesystem;
$eventDispatcher = new Dispatcher(new Container);
// Create View Factory capable of rendering PHP and Blade templates
$viewResolver = new EngineResolver;
$bladeCompiler = new BladeCompiler($filesystem, $pathToCompiledTemplates);
$viewResolver->register('blade', function () use ($bladeCompiler) {
return new CompilerEngine($bladeCompiler);
});
$viewResolver->register('php', function () {
return new PhpEngine;
});
$viewFinder = new FileViewFinder($filesystem, $pathsToTemplates);
$viewFactory = new Factory($viewResolver, $viewFinder, $eventDispatcher);
// Render template
return $viewFactory->make($viewName, $templateData)->render();
}
You can then call this using the following
view('view.name', ['title' => 'Title', 'text' => 'This is text']);
Yes you can use it where ever you like. Just install one of the the many packages available on composer for it.
If you're interested in integrating it with codeigniter I have a blog post here outlining the process.
Following the above steps should make it obvious how to include it into any framework.

The blade template engine can be used with codeigniter?

The template engine called blade can be used with codeigniter or pure php? I know that it can be used with laravel and I'd like to know if also can be used with any other php framework or with pure php
Blade can be used stand-alone in PHP.
This means you can comfortably use it in CodeIgniter.
https://github.com/PhiloNL/Laravel-Blade
Then again, you will need composer for that.
Alternatively you could use this CodeIgniter Library to simulate Blade: CodeIgniter Slice-Libray
It works pretty like Blade and it was designed directly for CodeIgniter!
For the record and as answer to another post:
I tested many libraries to run blade outside Laravel (that i don't use) and most (with all respect of the coders) are poor hacks of the original library that simply copied and pasted the code and removed some dependencies yet it retains a lot of dependencies of Laravel.
I created an alternative for blade that its free (MIT license, i.e. close source/private code is OK) in a single file and without a single dependency of an external library. You could download the class and start using it, or you could install via composes (composer require eftec/bladeone). So even composer is optional.
https://github.com/EFTEC/BladeOne
https://packagist.org/packages/eftec/bladeone
Its 100% compatible sans the Laravel's own features (extensions).
You can use BladeView library for CI.
NB: I ported this library
class Welcome extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->library("bladeview");
}
public function renderView(){
$data=array(
"name"=>"Jhon",
"age"=>21
);
$this->bladeview->render("test", $data);
}
public function renderString(){
$data=array(
"name"=>"Jhon",
"age"=>21
);
$string="Hello I'm \{{$name}}. My age is \{{$age}}";
$this->bladeview->render($string, $data,false);
}
}
then in view.blade.php you can render like you do in laravel blade.
Hello my name is {{$name}}. My Age is {{$age}}.
Output:
Hello my name is Jhon. My Age is 21.
I have done a full write up here: http://mstd.eu/index.php/2017/03/02/using-the-laravel-blade-templating-engine-in-codeigniter-3/
Basically, include the package with composer (you need to set CI up to use composer), then create a blade instance passing it your view and cache folder like so:
$blade = new BladeInstance(__DIR__ . "/../views", __DIR__ . "/../cache/views");
echo $blade->render("index");

Getting CakeS3 to work in the CakeShell

I want to be able to call the CakeS3 plugin from the Cake Shell. However, as I understand it components cannot be loaded from the shell. I have read this post outlining strategies for overcoming it: using components in Cakephp 2+ Shell - however, I have had no success. The CakeS3 code here is similar to perfectly functioning cake S3 code in the rest of my app.
<?php
App::uses('Folder','Utility');
App::uses('File','Utility');
App::uses('CakeS3.CakeS3','Controller/Component');
class S3Shell extends AppShell {
public $uses = array('Upload', 'User', 'Comment');
public function main() {
$this->CakeS3 = new CakeS3.CakeS3(
array(
's3Key' => 'key',
's3Secret' => 'key',
'bucket' => 'bucket')
);
$this->out('Hello world.');
$this->CakeS3->permission('private');
$response = $this->CakeS3->putObject(WWW_ROOT . '/file.type' , 'file.type', $this->CakeS3->permission('private'));
if ($response == false){
echo "it failed";
} else {
echo "it worked";
}
}
This returns an error of "Fatal error: Class 'CakeS3' not found in /home/app/Console/Command/S3Shell.php. The main reason I am trying to get this to work is so I can automate some uploads with a cron. Of course, if there is a better way, I am all ears.
Forgive me this "advertising"... ;) but my plugin is probably better written and has a better architecture than this CakeS3 plugin if it is using a component which should be a model or behaviour task. Also it was made for exactly the use case you have. Plus it supports a few more storage systems than only S3.
You could do that for example in your shell:
StorageManager::adapter('S3')->write($key, StorageManager::adapter('Local')->read($key));
A file should be handled as an entity on its own that is associated to whatever it needs to be associated to. Every uploaded file (if you use or extend the models that come with the plugin, if not you have to take care of that) is stored as a single database entry that contains the name of the config that was used and some meta data for that file. If you do the line of code above in your shell you will have to keep record in the table if you want to access it this way later. Just check the examples in the readme.md out. You don't have to use the database table as a reference to your files but I really recommend the system the plugin implements.
Also, you might not be aware that WWW_ROOT is public accessible, so in the case you store sensitive data there it can be accessed publicly.
And finally in a shell you should not use echo but $this->out() for proper shell output.
I think the App:uses should look like:
App::uses('CakeS3', 'CakeS3.Controller/Component');
I'm the author of CakeS3, and no I'm afraid there is no "supported" way to do this as when we built this plugin, we didn't need to run uploads from shell and just needed a simple interface to S3 from our controllers. We then open sourced the plugin as a simple S3 connector.
If you'd like to have a go at modifying it to support shell access, I'd welcome a PR.
I don't have a particular road map for the plugin, so I've tagged your issue on github as an enhancement and will certainly consider it in future development, but I can't guarantee that it would fit your time requirements so that's why I mention you doing a PR.

Developing/using a custom Resource Plugin in Zend Framework

We have used Zend_Log, which is configured in application.ini differently for different circumstances. We initialize it/get it in the bootstrap and store it in the registry:
$r = $this->getPluginResource('log');
$logger = $r->getLog();
But we've subclassed Zend_Log (say, Our_Log) to add customized features, and want to get it the same way. So then we have to make a new Resource Plugin. That seems quite easy - just copy Application/Resource/Log.php, rename the file to Ourlog.php, rename the class to class Zend_Application_Resource_Ourlog. For now, let's not worry about "Our_Log", the class -- just use the new Resource Plugin to get a Zend_Log, to reduce the variables.
So then, our new code in the bootstrap is:
$r = $this->getPluginResource('ourlog');
$logger = $r->getLog();
but of course this doesn't work, error applying method to non-object "r". According to the documentation,
"As long as you register the prefix path for this resource plugin, you
can then use it in your application."
but how do you register a prefix path? That would have been helpful. But that shouldn't matter, I used the same prefix path as the default, and I know the file is being read because I "require" it.
Anyway, any guidance on what simple step I'm missing would be greatly appreciated.
Thanks for the pointers -- so close, so close (I think). I thought I was getting it...
Okay, so I renamed the class Xyz_Resource_Xyzlog, I put it in library/Xyz/Resource/Xyzlog.php
Then, because I don't love ini files, in the bootstrap I put:
$loader=$this->getPluginLoader();
$loader->addPrefixPath('Xyz_Resource','Xyz/Resource/');
$r = $this->getPluginResource('xyzlog');
if (!is_object($r)) die ('Not an object!!');
Sudden Death. So, okay, do the ini:
pluginPaths.Xyz_Resource='Xyz/Resource/'
The same. No help. I believed that the basepaths of the plugin paths would include the PHP "include" paths. Am I mistaken in that? Any other ideas? I'll happily write up what finally works for me to help some other poor soul in this circumstance. Something to do with Name Spaces, maybe?
Plugin classes are resolved using the plugin loader, which works slightly differently to the autoloader; so just requiring the class in doesn't help you here. Instead, add this to your application.ini:
pluginPaths.Application_Resource = "Application/Resource"
you should then be able to use the class as normal. Since your path above will be checked before the default Zend one, you can also name your class 'Log' and still extend the Logger resource to override the standard functionality.

How can I detect, using php, if the machine has oracle (oci8 and/or pdo_oci) installed?

How can I detect, using php, if the machine has oracle (oci8 and/or pdo_oci) installed?
I'm working on a PHP project where some developers, such as myself, have it installed, but there's little need for the themers to have it. How can I write a quick function to use in the code so that my themers are able to work on the look of the site without having it crash on them?
if the oci extension isn't installed, then you'll get a fatal error with farside.myopenid.com's answer, you can use function_exists('oci_connect') or extension_loaded('oci8') (or whatever the extension's actually called)
The folks here have pieces of the solution, but let's roll it all into one solution.
For just a single instance of an oracle function, testing with function_exists() is good enough; but if the code is sprinkled throughout to OCI calls, it's going to be a huge pain in the ass to wrap every one in a function_exists() test.
Therefore, I think the simplest solution would be to create a file called nodatabase.php that might look something like this:
<?php
// nodatabase.php
// explicitly override database functions with empty stubs. Only include this file
// when you want to run the code without an actual database backend. Any database-
// related functions used in the codebase must be included below.
function oci_connect($user, $password, $db = '', $charset='UTF-8', $session_mode=null)
{
}
function oci_execute($statement, $mode=0)
{
}
// and so on...
Then, conditionally include this file if a global (say, THEME_TESTING) is defined just ahead of where the database code is called. Such an include might look like this:
// define("THEME_TESTING", true) // uncomment this line to disable database usage
if( defined(THEME_TESTING) )
include('nodatabase.php'); // override oracle API with stub functions for the artists.
Now, when you hand the project over to the artists, they simply need to make that one modification and they're good to go.
I dont know if I fully understand your question but a simple way would be to do this:
<?php
$connection = oci_connect('username', 'password', 'table');
if (!$connection) {
// no OCI connection.
}
?>
As mentioned above by Greg, programmatically you can use the function_exists() method. Don't forget you can also use the following to see all the environment specifics with your PHP install using the following:
<?php
phpinfo();
?>

Categories