I'm running a shell script via a cron job. It correctly sends an email. However I want to be able to pass data to the email template from the database which I seem unable to do.
Here is the shell
App::import('Core', 'Controller');
App::import('Component', 'Email');
class ExampleShell extends Shell {
var $uses = array('User');
function main() {
$users = $this->User->find('all');
$this->Controller =& new Controller();
$this->Email =& new EmailComponent(null);
$this->Email->initialize($this->Controller);
$this->Email->reset();
$this->Email->to = 'xx<xx#xx.com>';
$this->Email->subject = "Subject";
$this->Email->template = 'example';
$this->Email->sendAs = "both";
$this->Controller->set('users', $users);
$this->Email->send();
}
}
The variable $users does not seem to be available in the example.ctp file? How can I pass data from the shell script to the template please?
I managed to do it in following way
class ExampleShell extends Shell {
var $uses = array('User');
var $Controller = null;
function __construct(&$dispatch) {
App::import('Core', 'Controller');
App::import('Controller', 'App');
$this->Controller = & new Controller();
App::import('Component', 'Email');
$this->Email = new EmailComponent();
$this->Email->initialize($this->Controller);
parent::__construct($dispatch);
}
function main() {
$users = $this->User->find('all');
$this->Controller =& new Controller();
$this->Email =& new EmailComponent(null);
$this->Email->initialize($this->Controller);
$this->Email->reset();
$this->Email->to = 'xx<xx#xx.com>';
$this->Email->subject = "Subject";
$this->Email->sendAs = "both";
$this->Controller->set('users', $users);
$this->Email->send(null, 'template_1');
}
}
I hope it helps someone.
Make sure template is located where it should be app/views/elements/email/html/template_1.ctp and app/views/elements/email/text/template_1.ctp for text version. You should create layouts too in app/views/layouts/email/html/default.ctp and app/views/layouts/email/text/default.ctp
Related
Just getting started into laravel and need to run the same db query for 2 different views, I know I could just create 2 controllers and perform the same query in both passing it to each view.
But, is that the proper way? Or is there a way without repeating my code?
Thanks!
Edit:
I have the following function inside a controller:
protected function getLocation($url)
{
$match = ['url' => $url];
$location = DB::table('location')->where($match)->first();
if (!$location) {
abort(404);
}
return $location;
}
the controller is returning that data to a view:
public function showsubcatandlocation($service)
{
$category = $this->getCat($service);
$location = $this->getLocation($category);
$id = $category->id;
$locID = $location->id;
$profiles = $this->getProfileswLoc($id, $locID);
return view('category', ['profile' => $profiles]);
}
What's the proper way to reuse the getLocation function? Or should I just copy it in the new controller? I just need to use it in those 2 views.
maybe scope Query helps?
class Location extends Model
{
public function scopeMatch($query, $url)
{
return $query->where('url', $url);
}
}
And then your two controllel methods will be
$location = Task::match($url)->first();
if (!$location) {
abort(404);
}
return $location;
$category = $this->getCat($service);
$location = Task::match($category['url'])->first();
$id = $category->id;
$locID = $location->id;
$profiles = $this->getProfileswLoc($id, $locID);
return view('category', ['profile' => $profiles]);
I am currently working with magento 2.2.1 and I am having a weird problem. I am trying to get a set of data from database and display it on admin grid. I want to take records for a specific agent ID so i have a variable that has the value of the agent id. When i pass this variable as parameter to$this->collection->getSelect()->where('agent_id = ?', $this->givenAgentId); it wont display anything but if i replace $this->givenAgentId with it's value, for example with 4, it works perfectly!
This is my class:
<?php
namespace vendor\plugin\Ui\Component\Listing\DataProviders\Atisstats\Coupons;
use \vendor\plugin\Model\ResourceModel\Coupons\CollectionFactory;
use \Magento\Framework\Registry;
class Listing extends \Magento\Ui\DataProvider\AbstractDataProvider {
protected $_registry;
protected $givenAgentId = 0;
public function __construct(
Registry $registry,
$name,
$primaryFieldName,
$requestFieldName,
CollectionFactory $collectionFactory,
array $meta = [],
array $data = []
) {
parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
$this->_registry = $registry;
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$resource = $objectManager->get('\Magento\Framework\App\ResourceConnection');
$connection = $resource->getConnection();
$select = $connection->select()
->from(
['amasty_perm_dealer'],
['user_id']
);
$data = $connection->fetchAll($select);
foreach ($data as $dealerId) {
if ($dealerId['user_id'] == $this->_registry->registry('admin_session_id')) {
$this->givenAgentId = intval($this->_registry->registry('admin_session_id'));
}
}
if ($this->givenAgentId != 0) {
$this->collection->getSelect()->where('agent_id = ?', $this->givenAgentId);
} else {
$this->collection = $collectionFactory->create();
}
}
}
I have stuck here for hours!
I fixed this problem! First of all it was Registry class causing the problem so I used
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$resourceUserId = $objectManager->get('\Magento\Backend\Model\Auth\Session');
to get the user id from session and used it below to check the user! For some reason the registry object was modifying the variable holding the current users id!
I post the answer just in case someone get stuck with this kind of problem !
So I am using slim framework together with smarty and I don't want to repeat these lines of code:
require 'vendor/autoload.php';
require 'class.db.php';
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim();
$app->get('/', 'viewBooks');
$app->run();
function viewBooks()
{
//Dont want to repeat this
require_once('smarty/libs/Smarty.class.php');
$temp = new SmartyBC();
$temp->template_dir = 'views';
$temp->compile_dir = 'tmp';
//Dont want to repeat this end
$db = new db();
$data = $db->select("books");
$temp->assign('book', $data);
$temp->display('index.tpl');
$db = null;
}
As you can see I will have more function and will always include those lines. How can I transfer it to a function and just call it in my viewBooks function?
You could create a hook for this:
<?php
$app->hook('slim.before.dispatch', function() use ($app) {
//Your repetitive code
require_once('smarty/libs/Smarty.class.php');
$temp = new SmartyBC();
$temp->template_dir = 'views';
$temp->compile_dir = 'tmp';
//Inject your $temp variable in your $app
$app->temp = $temp;
});
function viewBooks() use ($app){
$db = new db();
$data = $db->select("books");
//Use your injected variable
$app->temp->assign('book', $data);
$app->temp->display('index.tpl');
$db = null;
}
How can I create a helper class in codeigniter to store all email which sends and receives in my website. I need to call that class with all email functions
$this->load->library('myclass');
If I call this class then this function should store $to,time, body and subject of the email to a table (table1). How it is possible?
Create a library with the name of "myemail" and place that in application/libraries.
application/libraries/myemail.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class CI_Myemail
{
public function __construct()
{
$this->CI =& get_instance();
}
public function saveEmail($to,$body,$subject)
{
$this->CI->load->model("table_model");
$this->table_model->save(array("to"=>$to,"body"=>$body,"subject"=>$subject,"mail_sent_time"=>date("Y-m-d H:i:s")));
}
}
Then you have to create table_model and write function to save the data into data.
In controller, you have to load this library as
$this->load->library('myemail');
In controller, you have to call as
$this->myemail->saveEmail($this->to,$body,$subject);// Here, $this->do is controller variable as you mentioned in comment
You can easily do this by having a helper function to send an email. Where ever you need to send the email call that function. Inside the function save the data to a table before calling the method to send the email. Also you can save the emails without sending with status pending and send it by a cronjob to improve user experience. I am doing same thing in my website.
The helper function as I am using it below. You can tune it for your needs. The data array should have all the details when called from a controller.
function sendEmail($data, $immediate=FALSE) {
$subject = $data['subject'];
$to = $data['to'];
$viewName = $data['template'];
$CI = & get_instance();
$CI->config->load("thephpcode.com");
$from = $CI->config->item('Sender');
$fromName = $CI->config->item('SenderName');
$priority = $CI->config->item('Priority');
if (isset($data['from'])) {
$from = $data['from'];
$fromName = $data['fromName'];
}
if (isset($data['priority']))
$priority = $data['priority'];
$body = $CI->load->view($viewName, $data, TRUE);
if ($from == "") {
log_message('error', 'From value is not set in Email helper for sending email');
return;
}
$bcc = '';
if (isset($data['bcc'])) {
$bcc = $data['bcc'];
}
/*
$replyto ='';
if (isset($data['reply_to'])) {
$replyto = $data['reply_to'];
$replytoname = $data['reply_to_name'];
}
*/
$status = 'Pending';
if ($immediate)
{
$status = 'Sent';
}
$dbdata = array();
$dbdata['from'] = $from;
$dbdata['fromName'] = $fromName;
if (isset($data['reply_to'])) {
$dbdata['replyto'] = $data['reply_to'];
$dbdata['replytoname'] = $data['reply_to_name'];
}
$dbdata['to'] = $to;
$dbdata['subject'] = $subject;
$dbdata['body'] = $body;
$dbdata['bcc'] = $bcc;
$dbdata['status'] = $status;
$dbdata['priority'] = $priority;
$CI->load->model('email_model', 'email_model');
$CI->email_model->insert($dbdata, 'email_queue');
if (!$immediate)
{
return TRUE;
}
//Send the email
$CI->load->library('email');
$CI->email->initialize($CI->config->item('email_config'));
$CI->email->from($from, $fromName);
$CI->email->to($to);
if (isset($data['bcc']))
{
$CI->email->bcc($data['bcc']);
}
if (isset($data['reply_to']))
{
$CI->email->reply_to($data['reply_to'],$data['reply_to_name']);
}
$CI->email->subject($subject);
$CI->email->message($body);
$CI->email->send();
return;
}
In CI, I have a model...
<?php
class User_crud extends CI_Model {
var $base_url;
var $category;
var $brand;
var $filter;
var $limit;
var $page_number;
public function __construct($category, $brand, $filter, $limit, $page_number) {
$this->base_url = base_url();
$this->category = $category;
$this->brand = $brand;
$this->filter = $filter;
$this->limit = $limit;
$this->page_number = $page_number;
}
public function get_categories() {
// output
$output = "";
// query
$this->db->select("name");
$this->db->from("categories");
$query = $this->db->get();
// zero
if ($query->num_rows() < 1) {
$output .= "No results found";
return $output;
}
// result
$output .= "<li><a class=\"name\">Categories</a></li>\n";
foreach ($query->result_array as $row) {
$output = "<li>{$row['name']}</li>\n";
}
return $output;
}
while I am calling this in my controller...
<?php
class Pages extends CI_Controller {
// home page
public function home() {
}
// products page
public function products($category = "cell phones", $brand = "all", $filter = "latest") {
// loading
$this->load->model("user_crud");
//
}
Now, How can I pass the $category, $brand and $filter variables to the user_crud model while loading/instantiation?
You shouldn't be using your model like this, just pass the items you need for the functions you require:
$this->load->model("user_crud");
$data['categories'] = $this->user_crud->get_categories($id, $category, $etc);
I would suggest (after seeing your code) that you study the fantastic codeigniter userguide as it has really good examples, and you just went a totally different way (treating model like an object). Its more simple sticking to how it was designed vs what you are doing.
You can not. A better idea would be to setup some setters in your model class along with some private vars and set them after loading the model.
if you return $this from the setters you can even chain them together like $this->your_model->set_var1('test')->set_var2('test2');