I trying to add DOM PDF library to my codeigniter application
1.Download dompdf and copy the dompdf folder to libraries folder.
2.Create file named Dompdf.php in libraries folder
In my controller
public function pdf_test()
{
$this->load->library('Dompdf');
$this->Dompdf->loadHtml('hello world');
$this->pdf->render();
$this->pdf->stream("welcome.pdf");
}
Dompdf.php
<?php defined('BASEPATH') OR exit('No direct script access allowed');
/**
* CodeIgniter PDF Library
*
* Generate PDF's in your CodeIgniter applications.
*
* #package CodeIgniter
* #subpackage Libraries
* #category Libraries
* #author Chris Harvey
* #license MIT License
* #link https://github.com/chrisnharvey/CodeIgniter-PDF-Generator-Library
*/
require_once(dirname(__FILE__) . '/dompdf/autoload.inc.php');
class Pdf extends DOMPDF
{
/**
* Get an instance of CodeIgniter
*
* #access protected
* #return void
*/
protected function ci()
{
return get_instance();
}
/**
* Load a CodeIgniter view into domPDF
*
* #access public
* #param string $view The view to load
* #param array $data The view data
* #return void
*/
public function load_view($view, $data = array())
{
$html = $this->ci()->load->view($view, $data, TRUE);
$this->load_html($html);
}
}
But i will this error.
Message: Class 'DOMPDF' not found
Filename: libraries/Dompdf.php
Line Number: 16
I am using latest DOMPDF
in my case. i use this
$dompdf = new Dompdf\DOMPDF();
require_once(_MAP."libraries/dompdf/autoload.inc.php");
$dompdf = new Dompdf\DOMPDF();
$html = 'rats :)';
$dompdf->load_html($html);
$dompdf->render();
$dompdf->stream("sample.pdf");
Starting with v0.7.0 Dompdf uses namespaces. You probably need to add a use statement prior to referencing the class. Or reference it using the full namespace path.
Try:
require_once(dirname(__FILE__) . '/dompdf/autoload.inc.php');
use Dompdf\Dompdf;
class Pdf extends Dompdf
{
...
}
Usage is available in the readme or on the wiki usage page.
I simply changed
$dompdf = new Dompdf\DOMPDF();
to
$dompdf = new Dompdf\Dompdf();
inside the Pdf.php
I have done pdf generation with tcpdf library but with a slightly different approach from you. Here is my solution with tcpdf. You can try it with Dompdf.
Download tcpdf and put in third_party folder
Make a file PDF.php in libraries folder with the following contents
require_once APPPATH."third_party/tcpdf/tcpdf.php";
class PDF extends TCPDF {
public function __construct() {
parent::__construct();
}
}
In controllers folder create a file Createpdf.php with following codes
defined("BASEPATH") OR exit("No direct script access allowed");
class Createpdf extends CI_Controller {
public function pdf()
{
$this->load->library("pdf");
$data["content"] = "Hello from CodeIgniter with TCPDF...";
$this->load->view("pdfreport", $data);
}
}
and the pdfreport.php view is:
$obj_pdf = new TCPDF('P', PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$obj_pdf->AddPage();
$obj_pdf->writeHTML($content, true, false, true, false, '');
$obj_pdf->Output('output.pdf', 'I');
First install it by composer
composer require dompdf/dompdf
And use this in pdf library .
require 'vendor/autoload.php';
use Dompdf\Dompdf as Dompdf;
Related
This is my init.php file required by the index.php file:
<?php
/**
*
* Initialization file: Will require all components we need.
*
**/
/* Set session */
session_start(); // Start session
/* Helpers */
require_once 'helpers/Sanitize.php'; // Sanatizing (escaping) strings
require_once 'helpers/Token.php'; // Generate tokens
require_once 'helpers/Hash.php'; // Hash class
require_once 'helpers/Input.php'; // Inputs manipulations
require_once 'helpers/Validation.php'; // Validation class
require_once 'helpers/Redirect.php'; // Redirect helper
require_once 'helpers/Session.php'; // Session manipulations
require_once 'helpers/Cookie.php'; // Cookies manipulations
/* Core */
require_once 'core/Config.php'; // Default global vairables
require_once 'core/App.php'; // Load App class from CORE
require_once 'core/Controller.php'; // Load Controller class from CORE
require_once 'core/Database.php'; // Load Database class
/* Models */
require_once '/www/myapp/models/System_user.model.php'; // System User Model
require_once '/www/myapp/models/user/User.model.php'; // User Model
require_once '/www/myapp/models/exec/something_usage.model.php'; // something model
require_once '/www/myapp/models/abc/abc.model.php'; // A class for handling trees
require_once '/www/myapp/models/Group.model.php'; // Group Model
require_once '/www/myapp/models/banana.model.php'; // A class for handling trees
// require_once '/www/myapp/models/Tree_db.php'; // A class for handling trees
As you can see, I am reacquiring all my classes files which is bad practice.
After a small research I found out that there is a function that autoloads classes whenever it is called:
// /* Autoload classes from directory */
// spl_autoload_register(function($class) {
// require_once 'classes/' . $class . '.php'; // No such directory
// });
I couldn't use it since my classes aren't in one folder and not easy to navigate to.
I continued my research and found out I can use a composer command composer dump-autoload -o that can require my code by declaring namespaces in the top of every class (following the folder structure) and use when using a specific class, and requiring autoload.php instead of the list mentioned above:
/* Composer */
require_once '../vendor/autoload.php'; // Loading composer components
I applied this change to all my classes - controllers classes files, models classes files (and subfolders classes files), core classes and database classes.
Example:
having the folder /www/app/models/system_users.model.php
I added the namespace App\Models; (and the class name is System_users), and if this class object is instantiated in an other class I use use App\Modal\System_uses; at the top of the file.
But I keep getting this error msg:
[22-Oct-2018 12:27:31] PHP Fatal error: Uncaught Error: Class 'Config' not found in /www/app/views/login/pages-login.php:14
Stack trace:
#0 /www/app/core/Controller.php(51): require_once()
#1 /www/app/controllers/login.php(27): app\Core\Controller->view('login/pages-log...')
#2 [internal function]: app\Controllers\Login->index()
#3 /www/app/core/App.php(51): call_user_func_array(Array, Array)
#4 /www/public/index.php(15): app\Core\App->__construct()
#5 {main}
thrown in /www/app/views/login/pages-login.php on line 14
[22-Oct-2018 12:27:31] PHP Fatal error: Class 'Controller' not found in /www/app/controllers/Error_404.php on line 7
[22-Oct-2018 12:27:31] PHP Stack trace:
[22-Oct-2018 12:27:31] PHP 1. {main}() /www/public/index.php:0
[22-Oct-2018 12:27:31] PHP 2. app\Core\App->__construct() /www/public/index.php:15
[22-Oct-2018 12:27:31] PHP 3. require_once() /www/app/core/App.php:31
Might be because I'm not requiring my Config class in the views. But up until now using requre once everything worked fine, and i really find it bothering using use App\Core\Config; in top of every view.
How is the proper way to handle this kind of situation with namespaces?
EDIT:
Im adding my code structure:
/www/public/index.php
<?php
use MyApp\Core\App;
/**
*
* Index: First page a user visits.
*
**/
# Reuiring init.php: Responsible for initializing classes we want to use.
require_once '../myapp/init.php';
# Initialize App class
$app = new App();
/www/myapp/core/controller.php
<?php
namespace MyApp\Core;
use MyApp\Models\System_user;
use MyApp\Core\Config;
/**
*
* Controller instance:
*
*/
class Controller
{
/*=================================
= Variables =
=================================*/
# System User
protected $system_user;
/*===============================
= Methods =
================================*/
/**
*
* Model Class: Loads a requested model
* #param $model String Gets a model name
*
*/
protected function model($model)
{
require_once '../myapp/models/' . $model . '.php';
return new $model();
}
/**
*
* View Class: Loads a requested view
* #param $view String Gets a view name
* #param $data Array (optional) Gets an array of variables to pass to the view
* #throws Plain view
*
*/
protected function view($view, $data=[])
{
require_once '../myapp/views/' . $view . '.php';
}
/**
*
* Check if a user is logged in
*
*/
protected function is_loggedin()
{
...
}
/www/myapp/core/app.php
<?php
namespace MyApp\Core;
// use MyApp\Core\Controller;
use MyApp\Controllers;
/**
*
* App instance: Handles controlles (specifically gets routs data)
*
*/
class App
{
protected $controller = 'Error_404';
protected $method = 'index';
protected $parameters = array();
protected $contollerNamespace;
public function __construct()
{
# Get parsed URL
$url = $this->parseUrl();
# Check if contorller via input-url exists in the controller folder
if (file_exists('../myapp/controllers/' . $url[0] . '.php')){
$this->controller = $url[0]; // Replace current 'home' controller with the new one
$this->contollerNamespace = 'MyApp\\Controllers\\'.$url[0];
unset($url[0]); // Remove controller name from the array.
}
# Require the controllers class via controllers folder
require_once '../myapp/controllers/' . $this->controller . '.php';
# Create a new obect of the controller (by its name)
$this->controller = new $this->contollerNamespace; // ex: new Home() -- or: new Login()
# Chech if method is passed
if ( isset($url[1]) ) {
# Check if method exists in class
if ( method_exists($this->controller, $url[1]) ) {
# Set new method variable
$this->method = $url[1];
unset($url[1]);
}
}
# Set parameters (if any).
$this->parameters = $url ? array_values($url) : [];
# Summon controller with the relevant method and variables.
call_user_func_array([$this->controller, $this->method], $this->parameters);
}
/**
*
* Parses the url - Gets the $_GET input via .htaccess definition.
*
*/
public function parseUrl()
{
if ( isset($_GET['url']) ) {
return $url = explode('/', filter_var(rtrim($_GET['url'], '/'), FILTER_SANITIZE_URL));
}
}
}
/www/myapp/controllers/login.php
<?php
namespace MyApp\Controllers;
use MyApp\Core\Controller;
use MyApp\Models\System_user;
use MyApp\Core\Config;
/**
* Login Class
*/
class Login extends Controller
{
/**
*
* Login Main login Form
*
*/
public function index($name ='')
{
// Create a new system user
$system_user = new System_user();
// If user is logged in - Redirect to dashboard
if ( $system_user->check_logged_in() )
Redirect::to('dashboard'); // Redirect to login form
else
$this->view('login/pages-login'); // Redirect to login form
}
/**
*
* User login: Creates the user login.
*
*/
public function user_login()
{
...
}
}
Composer runs on the PSR-4 autoloading standard.
https://www.php-fig.org/psr/psr-4/
In your composer.json, add an autoloader namespace for your classes. For example, in my form package, it looks like this:
"autoload": {
"psr-4": {
"Del\\Form\\": "src/",
"DelTesting\\Form\\": "tests/unit/Del/Form/"
}
},
What is this saying? Esentially all classes in src/ will have namespace Del\Form.
So, for instance, src/Form.php would look like this:
<?php
namespace Del\Form;
class Form
{
// code
}
Take note, the classname should match the filename, that is class Form should be called Form.php.
Now if you create folders in src, those get added to the namespace. Another example, src/Field/Text.php would look like this:
<?php
namespace Del\Form\Field;
class Text
{
// code
}
If you stick to these conventions, everything will autoload.
After editing composer.json to add the namespace, run composer dumpautoload to generate the classmaps that composer uses.
I am trying to load a custom class in my CakePHP3 project, although I can't seem to find out what I am missing.
I have a folder src/Library with Config.php in it:
<?php
namespace App\Library;
/**
* Class containing CONST values for important settings
*
* #version 1.0
* #author berry
*/
class Config
{
const UPLOAD_DIRECTORY = './upload/';
}
I put use App\Library\Config; in my PicturesController, which Visual Studio even recognizes as a valid class (I can access the const through intellisense)
Here is my controller:
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Filesystem\Folder;
use Cake\Filesystem\File;
use App\Library\Config;
/**
* Pictures Controller
*
* #property \App\Model\Table\PicturesTable $Pictures
*/
class PicturesController extends AppController
{
public function upload()
{
if($this->request->is('post'))
{
$oConfig = new Config();
$oUploadDir = new Folder($oConfig::UPLOAD_DIRECTORY);
debug($oUploadDir);
$aFile = $this->request->data('submittedfile');
}
}
So despite my IDE even registering the class (and telling me I'm using it correctly) I get Class 'App\Library\Config' not found thrown in the browser.
I changed the name from Library to Berry (My first name).
Apparently you can't call it Library. Probably used somewhere else in Cake.
I am trying to use GeoIP2 PHP API ( https://github.com/maxmind/GeoIP2-php ) within CodeIgniter. How can I load GeoIP2 and use it for user geolocation?
I have tried loading it like this:
$this->load->library("GeoIp2/Database/Reader");
or
require APPPATH . "libraries/GeoIp2/ProviderInterface.php";
require APPPATH . "libraries/GeoIp2/Database/Reader.php";
or
$this->load->file("GeoIp2/ProviderInterface");
$this->load->library("GeoIp2/Database/Reader");
I get this error: "Unable to load the requested file: ProviderInterface"
I have looked this Namespace in PHP CodeIgniter Framework , but i have little experience with namespaces.
No success with this, I am not winning, I really do not know how to implement this within CodeIgniter.
I was trying to find the solution of this question. But couldn't find on stackoverflow. I am writing my own code here. Maybe, it will be helpful for someone. I have added a new function in my utility_helper.php file :
function get_ip_country_code($ip_address) {
require APPPATH .'third_party/GeoIP2/autoload.php';
$reader = new GeoIp2\Database\Reader(FCPATH.'public/geoip/GeoIP2-Country.mmdb');
$record = $reader->country($ip_address);
return $record->country->isoCode;
}
I put the GeoIP2 library in the third_party folder and put the mmdb file in the public folder. It works fine for me. I hope it will save someone's time :)
The GeoIp2 php sdk takes advantage of PHP's namespace feature, which the CodeIgniter framework does not support, which is why you're getting the error when you try to load the library. The post you linked to offers a solution using spl_autoload, however I do not use CodeIgniter and haven't tested it with the GeopIp2 php sdk.
Few ways you can embed this within CodeIgniter.
First, you need to include it within the script:
require_once( 'GeoIp2/vendor/autoload.php' );
use GeoIp2\Database\Reader;
Next, I call Reader() for the detection methods
$reader = new Reader('GeoIp2/GeoIP2-City.mmdb');
$record = $reader->city($ip);
// Country (code)
$record->country->isoCode;
// State
$record->mostSpecificSubdivision->name;
// City
$record->city->name;
// zip code
$record->postal->code;
I just tested this on CodeIgniter 3x and works.
I used a bridge class. Inside /application/libraries create a file called CI_GeoIp2.php and add the following code.
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* GeoIp2 Class
*
* #package CodeIgniter
* #subpackage Libraries
* #category GeoIp2
* #author Timothy Marois <timothymarois#gmail.com>
*/
require_once( APPPATH . 'third_party/GeoIp2/vendor/autoload.php' );
use GeoIp2\Database\Reader;
class CI_GeoIp2 {
protected $record;
protected $database_path = 'third_party/GeoIp2/GeoIP2-City.mmdb';
public function __construct() {
$ci =& get_instance();
$reader = new Reader(APPPATH.$this->database_path);
$ip = $ci->input->ip_address();
if ($ci->input->valid_ip($ip)) {
$this->record = $reader->city($ip);
}
log_message('debug', "CI_GeoIp2 Class Initialized");
}
/**
* getState()
* #return state
*/
public function getState() {
return $this->record->mostSpecificSubdivision->name;;
}
/**
* getState()
* #return country code "US/CA etc"
*/
public function getCountryCode() {
return $this->record->country->isoCode;
}
/**
* getCity()
* #return city name
*/
public function getCity() {
return $this->record->city->name;
}
/**
* getZipCode()
* #return Zip Code (#)
*/
public function getZipCode() {
return $this->record->postal->code;
}
/**
* getRawRecord()
* (if you want to manually extract objects)
*
* #return object of all items
*/
public function getRawRecord() {
return $this->record;
}
}
Now you can either autoload or load it up using
$this->load->library("CI_GeoIp2");
I prefer to autoload it like this under autoload.php config
$autoload['libraries'] = array('CI_GeoIp2'=>'Location');
So within the script I use,
$this->Location->getState()
$this->Location->getCity()
... and so on
I'm currently building some tests for my Image model which handles files and wanted to use vsfStream to test the file manipulations.
I can't seem to get my tests to recognise the vsfClass.
The vsfStream library is in app/Vendor/vsfStream
My ImageTest.php file is as follows:
<?php
App::uses('Image', 'Model');
App::uses('vfsStream', 'Vendor');
//App::import('Vendor', 'vfsStream', array('file' => 'vfsStream' . DS . 'vfsStream.php'));
/**
* Image Test Case
*
*/
class ImageTest extends CakeTestCase {
/**
* Fixtures
*
* #var array
*/
public $fixtures = array(
'app.image',
'app.contractor',
'app.project',
'app.project_contractor',
'app.project_image'
);
/**
* setUp method
*
* #return void
*/
public function setUp() {
parent::setUp();
$this->Image = ClassRegistry::init('Image');
$this->root = vfsStream::setup('exampleDir');
}
...more code
I get the error
Error: Class 'vfsStream' not found
File: C:\xampp\htdocs\sgaluminium\app\Test\Case\Model\ImageTest.php
Line: 32
Any help would be appreciated. Thanks
It seems that vsfStream was not loaded correctly. Did you load it with composer? I recommend you use this composer plugin: https://github.com/uzyn/cakephp-composer (read the how-to-use section on their website) and you write your composer.json like this:
{
"require-dev": {
"phpunit\/phpunit": "3.7.35",
"mikey179/vfsStream": "1.2"
}
}
This setup works very well in my project. In my test-file I use:
App::uses('vfsStream', 'Vendor');
just like you do.
I've got a class library in defined here .../projectname/library/Me/Myclass.php defined as follows:
<?php
class Me_Myclass{
}
?>
I've got the following bootstrap:
<?php
/**
* Application bootstrap
*
* #uses Zend_Application_Bootstrap_Bootstrap
*/
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
/**
* Bootstrap autoloader for application resources
*
* #return Zend_Application_Module_Autoloader
*/
protected function _initAutoload()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Default',
'basePath' => dirname(__FILE__),
));
$autoloader->registerNamespace('Me_');
return $autoloader;
}
/**
* Bootstrap the view doctype
*
* #return void
*/
protected function _initDoctype()
{
$this->bootstrap('view');
$view = $this->getResource('view');
$view->doctype('XHTML1_STRICT');
}
/**
* Bootstrap registry and store configuration information
*
* #return void
*/
protected function _initRegistry()
{
$config = new Zend_Config_Ini(APPLICATION_PATH .
'/configs/application.ini', APPLICATION_ENV,
array('allowModifications'=>true));
Zend_Registry::set('configuration', $config);
}
}
In my controller I try to instantiate the class like this:
<?php
class SomeController extends Zend_Controller_Action
{
public function indexAction()
{
$classMaker=new Me_Myclass();
}
}
?>
When I navigate directly to http:/something.com/projectname/some?id=1 I get the following error:
Fatal error: Class 'Me_Myclass' not found in /home/myuser/work/projectname/application/controllers/SomeController.php on line x
Any ideas?
Potentially Pertinent Miscellany:
The autoloader seems to work when I'm extending models with classes I've defined in other folders under application/library.
Someone suggested changing the 'Default', which I attempted but it didn't appear to fix the problem and had the added negative impact of breaking function of models using this namespace.
You class needs to be name Me_Myclass:
class Me_Myclass
{
}
Move your library folder up a level so that you have the folder structure:
/
/application
/library
/public
And then in your Bootstrap add the following to the _initAutoload():
Zend_Loader_Autoloader::getInstance()->registerNamespace('Me_');
you can define the autoload dir in the config.ini file like this:
autoloaderNamespaces[] = "Me_"
;You could add as many as you want Classes dir:
autoloaderNamespaces[] = "Another_"
autoloaderNamespaces[] = "Third_"
works 100%
I think #smack0007 means replace the contents of your _initAutoload method with Zend_Loader_Autoloader::getInstance()->registerNamespace('Me_'); so it looks like this:
protected function _initAutoload()
{
Zend_Loader_Autoloader::getInstance()->registerNamespace('Me_');
}
Not sure if this is your problem, but I just spent the last day and half trying to figure out my own similar problem (first time loading it up on Linux from Windows). Turns out I was blind to my library's folder name case.
/library
/Tlib
is not the same as (on *nix)
/library
/tlib
Class name is typically this
class Tlib_FooMe {
...
}
Hope this helps someone who is similarly absentminded.