I develop a component that use a form submission in both front-end and back-end.
I use getForm like weblink component.
Now, getForm() works in Back-end but in front-end not work, It generate error message about Jform.
I can not know the weblink component in view and model(form) and what it has done to show form.
require_once JPATH_COMPONENT_ADMINISTRATOR.'/models/shop.php';
JTable::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR . '/tables');
class componentNameModelShopForm extends componentNameModelShop
{
public function getForm($data = array(), $loadData = true)
{
$form = $this->loadForm('com_componentName.shop', 'shop', array('control' => 'jform', 'load_data' => $loadData));
if (empty($form))
{
return false;
}
return $form;
}
}
This class also has getItem() and loadFormData() method.
$form in back-end work good but in front-end always be false;
in front-end i extends this model class and before the class declaration i include_once it.
By adding this two line before $this->ladForm() it works good, without including JTable.
JForm::addFormPath(JPATH_COMPONENT_ADMINISTRATOR . '/models/forms');
JForm::addFieldPath(JPATH_COMPONENT_ADMINISTRATOR . '/models/fields');
Related
I used Twig with Symfony and I really loved it. I now have a CodeIgniter project and I want to integrate Twig with it.
I installed the latest versions of CodeIgniter and Twig via Composer and and followed this tutorial but I believe the code in the tutorial is for CI v3.
Could anyone who has integrated Twig with CI v4 help me with the proper code please.
UPDATE
solution below!
Try this I hope it will help you
Install Composer and run the following command to get the latest version:
composer require "twig/twig:^3.0"
Then after installation add this line of code to the baseController initController method just after the parent::initController, just like the code below
namespace App\Controllers;
use CodeIgniter\Controller;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
class BaseController extends Controller
{
protected $helpers = [];
protected $twig;
// protected $helper = [];
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
parent::initController($request, $response, $logger);
$appPaths = new \Config\Paths();
$appViewPaths = $appPaths->viewDirectory;
$loader = new \Twig\Loader\FilesystemLoader($appViewPaths);
$this->twig = new \Twig\Environment($loader, [
'cache' => WRITEPATH.'/cache/twig',
]);
}
}
So with this now you can call the view files in other controllers extends to parent controller BaseController
e.g
namespace App\Controllers;
class Home extends BaseController
{
public function index ()
{
// To load a template from a Twig environment, call the load() method which returns a \Twig\TemplateWrapper instance:
$template = $this->twig->load('index.html');
// To render the template with some variables, call the render() method:
return $template->render(['the' => 'variables', 'go' => 'here']);
// The display() method is a shortcut to output the rendered template.
// OR You can also load and render the template in one fell swoop:
return $this->twig->render('index.html', ['the' => 'variables', 'go' => 'here']);
// If a template defines blocks, they can be rendered individually via the renderBlock() call:
return $template->renderBlock('block_name', ['the' => 'variables', 'go' => 'here']);
// Note any of them above will work
}
}
If you still want to use view() with twig like codeigniter 4 default view function you can modify the Common.php file in app directory
by adding this block of code below.
if (!function_exists('view'))
{
function view($tpl, $data = []) {
$appPaths = new \Config\Paths();
$appViewPaths = $appPaths->viewDirectory;
$loader = new \Twig\Loader\FilesystemLoader($appViewPaths);
$twig = new \Twig\Environment($loader, [
'cache' => WRITEPATH.'/cache/twig',
]);
if (!stripos($tpl, '.twig')) {
$tpl = $tpl . '.twig';
}
return $twig->render($tpl, $data);
}
}
Then in controller call it like this
return view('index', ['name' => 'Chibueze Agwu'])
Then in view file index.twig
<!DOCTYPE html>
<html>
<head>
<title>My Webpage</title>
</head>
<body>
<h1>My Webpage</h1>
{{ name }}
</body>
</html>
This will output
My Webpage
Chibueze Agwu
I haven't test this code but I hope it will work. If not call my attentions.
In order to obey the the rule of DRY (DO NOT REPEAT YOURSELF), you can go ahead to improve the code I will do that later
I found the solution some time ago and I'm posting it in case some people stumble across the question.
First of all, all your controllers must extend BaseController; this controller is available by default when you install CodeIgniter 4.
Create a custom helper file and put in [project-name]/appstarter/app/Helpers.
IMPORTANT
the name of your helper must be [name]_helper.php or it will not work!
for example mine is called custom_helper.php
Create the following function in the custom helper you just created:
use Twig\Environment;
use Twig\Extension\DebugExtension;
use Twig\Loader\FilesystemLoader;
use Twig\TwigFilter;
if (!function_exists('twig_conf')) {
function twig_conf() {
// the follwing line of code is the only one needed to make Twig work
// the lines of code that follow are optional
$loader = new FilesystemLoader('Views', '../app/');
// to be able to use the 'dump' function in twig files
$twig = new Environment($loader, ['debug' => true]);
$twig->addExtension(new DebugExtension());
// twig lets you create custom filters
$filter = new TwigFilter('_base_url', function ($asset) {
return base_url() . '/' . $asset;
});
$twig->addFilter($filter);
return $twig;
}
}
NOTE
before creating any custom filter, make sure Twig doesn't already has one built-in.
Now in the BaseController you'll find an empty array called $helpers. You must put the name of your custom helper in it. Mine is called custom_helper.php; so the code looks like this for me:
protected $helpers = ['custom'];
Just below the array you'll find the constructor for BaseController and this is where the Twig library will be initialized; by calling the function you created in your custom helper:
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) {
parent::initController($request, $response, $logger);
$this->twig = twig_conf();
}
Now you are good to go! To render your twig files in any controller:
return $this->twig->render('twig_name', $dataArray);
Try this I hope it will help you.
Install Composer and run the following command to get the latest version:
composer require "twig/twig:^3.0"
Just wondering if this is a good way to write ajax code to interact with Laravel routes?
Example my application's require to list all customer data and also list all country through ajax. I have 3 controller ApiController, CustomerController, CountryController.
So in my routes.php I have this routes
Route::get('api/v1/ajax/json/{class}/{function}', 'Api\v1\ApiController#ajaxreturnjson');
In the ApiController.php, I have below function to call other controller function to return the data I need.
class ApiController extends Controller
{
public function ajaxreturnjson(Request $request, $controller, $function){
$input = $request->input();
if($request->input('namespace') != ''){
$namespace = $request->input('namespace');
unset($input['namespace']);
}else{
$namespace = 'App\Http\Controllers';
}
$data = array();
try {
$app = app();
$controller = $app->make($namespace.'\\'.$controller);
$data = $controller->callAction($function, array($request)+$input);
} catch(\ReflectionException $e){
$data['error'] = $e->getMessage();
}
return response()->json($data);
}
}
So example to use the ajax, I just need to pass the class name, namespace and also the function name to the ajax url.
Example to retrieve all customer info.
$.ajax({
dataType:"json",
url:"api/v1/ajax/json/CustomerController/getList",
data:"namespace=\\App\\Http\\Controllers\\",
success:function(data){
}
})
So in this way, I don't have to create so many routes for different ajax request.
But I am not sure if this will cause any security issue or is this a bad design?
Personally, I would not do it this way. Sure, you could do it this way, but it's not very semantic and debugging it could be a pain.
Also, if someone else begins working on the project, when they look at your routes file, they won't have any idea how your app is structured or where to go to find things.
I think it's better to have a controller for each Thing.
Im new to codeigniter and im developing my first web application with it and want to make sure im doing best practices the 1st time so i dont have to go back to make corrections down the road. with that said, here is what im doing.
I want to edit a note in the DB, then after the record has been updated redirect to a different page.
my model is coded correctly so im not worried there, but the controller looks like this (and this is probably not correct:
public function edit($id) {
$this->load->model('Notes_model');
if (isset($_POST["edit"]))
{
$data['data'] = $this->Notes_model->edit($id);
$url = "/Notes/view/" . $id;
redirect($url);
}
$data['notes'] = $this->Notes_model->viewNotes($id);
$this->load->view('templates/header');
$this->load->view('notes/edit', $data);
$this->load->view('templates/footer');
}
hopefull this makes sense, basically what I'm wanting to do here is:
1.) Show the edit note page
2.) if i edited that page by hitting submit
a.) update the db
b.) redirect to a different page.
does this look pretty good or should i make some better changes?
Although your controller code is fine but one thing you have to take care that you should load model in the constructor of your controller so you don't have to include the model in each function same recommendations for the libraries, helpers this is the best practice
class myclass extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->model('Notes_model');
$this->load->helper(form);
}
public function myfunction(){
}
}
Here is the starting tutorial with MVC standards advanced-codeigniter-techniques-and-tricks
<?php
class Home extends CI_Controller
{
function __construct() {
parent::__construct();
$this->m_auth->notLogin();
$this->load->library('form_validation');
$this->load->library('ajax_pagination');
$this->load->library('dateconverter');
$this->load->helper('template');
$this->load->helper('check');
$this->load->model('mymodels/crud_model');
$this->lang->load('personal', $this->m_auth->get_language());
$this->lang->load('global', $this->m_auth->get_language());
}
function index()
{
$this->get_recs();
}
function get_recs()
{
//get for view or first page to be showed
}
/**
* Register New User
*/
function updateRecords()
{
$this->form_validation->set_rules('ministery','<span class="req">(Ministry)</span>','trim|required');
$this->form_validation->set_rules('directorate','<span class="req">(Directorate)</span>','trim|required');
if($this->form_validation->run()==FALSE)
{
header_tpl($this->m_auth->get_language(),'a');
banner_tpl($this->m_auth->get_language(),'a');
left_tpl($this->m_auth->get_language(),'a');
$content = $this->load->view('personal/edit_personal', $this->POST,true);
content_tpl($content);
footer_tpl();
}
else
{
$form_data = array(
'ministry' => $this->input->post('ministery'),
'directorate' => $this->input->post('directorate'),
'job_province' => $this->input->post('job_province'),
'job_district' => $this->input->post('job_district'),
'first_name' => $this->input->post('fname'),
'last_name' => $this->input->post('lname')
);
if($this->crud_model->update_recs('ast_emp_property',$form_data)==TRUE)
{
$this->session->set_flashdata("msg","<span class='m_success'>".$this->lang->line('global_insert_success')."</span>");
redirect('/home/success_reg/'.$id.'','refresh');
}
else
{
$this->session->set_flashdata("msg","<span class='m_error'>".$this->lang->line('global_insert_error')."</span>");
redirect('home','refresh');
}
}
}
}
?>
I'm trying to working with Security component in a Controller of CakePHP 2.0 but I'm doing something wrong with it.
I've read in the documentation, but when I include the Security component in my Controller and I call the controller action register I get a blank page. If I comment the include public $components = array('Security'); it works again, where I'm wrong?
<?php
App::uses('CakeEmail', 'Network/Email');
class UsersController extends AppController {
public $components = array('Security');
public function register () {
if (!empty($this->data)) {
if ($this->data['User']['password'] == $this->data['User']['confirm_password']) {
$this->User->create();
$this->User->save($this->data);
$this->registrationEmail ($this->data['User']['email'], $this->data['User']['username']);
$this->redirect(array('controller'=>'users', 'action'=>'registration', 'success'));
}
}
}
private function registrationEmail ($account_email, $username) {
$email = new CakeEmail('myconfig');
$email->from(array('mailer#email.com' => 'MySite.com'));
$email->to($account_email);
$email->subject('Account activation / MySite.com');
$email->template('activation');
// $this->set('activation_code', Security->hash($account_email));
$email->viewVars(
array(
'activation_code' => $this->Security->hash($account_email),
'username' => $username
)
);
$email->send();
}
?>
How is the registration form rendered in your view file?
If you're using the Security Component, all form fields need to be generated using the FormHelper. In addition you can't fiddle with hidden values on the front end once they've been given a value by the FormHelper.
I followed this tutorial: http://codeigniter.com/wiki/Internationalization_and_the_Template_Parser_Class/
The controller that loads the language is this one:
<?php
class Example extends Controller {
function Example() {
parent::Controller();
# Load libraries
$this->load->library('parser');
# Load language
$this->lang->load('example', 'english');
}
function index() {
# Load variables into the template parser
$data = $this->lang->language;
# Display view
$this->parser->parse('example', $data);
}
}
?>
In order to change the language I have to manually change english to say spanish in the controller.
What's the best way the user can do this from the index.php file (view)?
The best thing to do is have the user select a supported language on some page, set it as a session variable and call it when ever you need to load a language
$language = $this->session->userdata("language");
$this->lang->load("example", $language);
$data = $this->lang->language;
$this->parser->parse("example", $data);
EDITED BELOW
If you're using CodeIgniter and you're new to this, I wouldn't suggest messing with the index.php file.
You want to do it inside your controller by loading a form where they can pick their language and storing it in the session. I'd also suggest autoloading your session library.
The controller:
<?php
class Home extends Controller {
function Home()
{
parent::Controller();
$this->load->library("session");
}
function index()
{
$language = $this->session->userdata("language");
$this->lang->load("example", $language);
$data = $this->lang->language;
$this->parser->parse("example", $data);
}
function set_lang()
{
if( ! $this->form_validation->run())
{
$this->load->view("select_language_form");
}
else
{
$language = $this->input->post('language', TRUE);
$this->session->set_userdata('language', $language);
redirect('home' 'location');
}
}
}