I want to implement a Sugar Logic Hook that fires when invoice status change to 'Validated'.
This my logic hook :
<?php
$hook_version = 1;
$hook_array = Array();
$hook_array['after_save'] = Array();
$hook_array['after_save'][] = Array(1, 'status invoices Changes', '/var/www/html/suitecrm/modules/AOS_Invoices/AOS_LogicHooks.php','AOS_LogicHooks', 'statusInvoicesChanges');
?>
This is my action class:
<?php class AOS_LogicHooks {
public function statusInvoicesChanges (SugarBean $bean, $event, $arguments){
if($bean->status == 'Validated' && $bean->fetched_row->status <> $bean->status){
$GLOBALS['log']->fatal("Status has been changed");
}}}
?>
What do I missing?
Simple mistake we all do, fetched row is an Array so you cannot access the content as a property.
I just tested this and works fine! take a look:
<?php
class AOS_LogicHooks
{
public function statusInvoicesChanges(SugarBean $bean, $event, $arguments)
{
if ($bean->status == 'Validated' && !empty($bean->fetched_row) && $bean->fetched_row['status'] <> $bean->status) {
$GLOBALS['log']->fatal("Status has been changed");
}
}
}
Related
This question already has answers here:
Reference - What does this error mean in PHP?
(38 answers)
Closed 5 years ago.
So, i'm working on building my first MVC based application.
I followed this tutorial: requiremind.com/a-most-simple-php-mvc-beginners-tutorial/ and now i'm creating a forum based on the above tutorial.
This is in my index.php
if(isset($_GET['controller']) && !isset($_GET['action'])) {
$controller = $_GET['controller'];
$action = 'topic';
} else {
$controller = 'main';
$action = 'index';
}
The first condition is for displaying pages with topic and will work for url with ?controller=PHP or something like this and set the $action as 'topic'.
Now the request will be transferred to routes.php
function call($controller, $action) {
require_once('controllers/main_controller.php');
if($controller == 'main') {
require_once('models/main_model.php');
$controller = new MainController();
} else {
require_once('models/topic_model.php');
$controller = new MainController();
}
$controller->$action();
}
$db = Db::getInstance();
$query = $db->query('SELECT cat_name FROM category');
$categories = $query->fetchAll();
foreach($categories as $category_name) {
if($controller == $category_name && $action == 'topic') {
call($controller, $action);
}
}
if(($controller == 'main') && ($action == 'index')) {
call($controller, $action);
}
Now this will make a request with database and if the topic/category exists, it will call the function.
main_controller.php
class MainController {
public function index() {
$category = Main::home();
require_once('views/home.php');
}
public function topic() {
$topics = Topic::thread_topic($_GET['controller']);
require_once('views/topic.php');
}
}
After the main_controller.php, topic_model.php:
<?php
class Topic {
public $thread_topic;
public $thread_desc;
public $thread_created_at;
public $thread_created_by;
public $category_id;
public function __construct($thread_topic, $thread_desc, $thread_created_at, $thread_created_by, $category_id) {
$this->thread_topic = $thread_topic;
$this->thread_desc = $thread_desc;
$this->thread_created_at = $thread_created_at;
$this->thread_created_by = $thread_created_by;
$this->category_id = $category_id;
}
public function thread_topic($controller) {
$list = [];
$cat_id = Fnct::cat_name_to_id($controller);
$db = Db::getInstance();
$stmt = prepare('SELECT * FROM thread WHERE thread_created_by =:cat_id');
$stmt->execute(array(':cat_id' => $cat_id));
foreach($stmt->fetchAll() as $thread) {
$list[] = new Topic($thread['thread_topic'], $thread['thread_desc'], $thread['thread_created_at'], $thread['thread_created_by'], $thread['category_id']);
}
return $list[];
}
}
?>
And now the views/topic.php
<table border='1'>
<tr>
<th>Thread Topic</th>
<th>Thread Desc</th>
<th>Thread Started At</th>
</tr>
<tr>
<?php foreach($topics as $topic) { ?>
<td><?php echo $topic->thread_topic; ?></td>
<td><?php echo $topic->thread_desc; ?></td>
<td><?php echo $topic->thread_created_at; ?></td>
<?php } ?>
</tr>
</table>
The problem is this, it is displaying blank page. And giving no error.
And i'm still struggling to figure out what is wrong here. Please tell me what i did wrong here??
Edit: In routes.php moves $controller = new MainController() under if statement. But still same blank page is displaying.
Well, your error is in your routes.php as mentioned above. I'll try to explain it here in an answer and also directly fix the mistakes you did.
Okay, lets start. First of all, lets ignore the call() function first and only look at the other part:
Your Code:
$db = Db::getInstance();
$query = $db->query('SELECT cat_name FROM category');
$categories = $query->fetchAll();
foreach($categories as $category_name) {
if($controller == $category_name && $action == 'topic') {
call($controller, $action);
}
}
if(($controller == 'main') && ($action == 'index')) {
call($controller, $action);
}
You should know that fetchAll() will always return an arrqay, not a string, thats why you can't compare the result directly with a string. Change the code to:
$db = Db::getInstance();
$query = $db->query('SELECT cat_name FROM category');
$categories = $query->fetchAll();
foreach($categories as $category_name) {
if($controller == $category_name["cat_name"] && $action == 'topic') {
call($controller, $action);
}
}
if(($controller == 'main') && ($action == 'index')) {
call($controller, $action);
}
You see the $categoriy_name["cat_name"] - You have to give the key, since $category_name is an array, not a string. (May look at some tutorials for PHP and SQL, like how all the fetch method works and what their output is).
And then the second part, your call function
Your code:
function call($controller, $action) {
require_once('controllers/main_controller.php');
$controller = new MainController();
if($controller == 'main') {
require_once('models/main_model.php');
} else {
require_once('models/topic_model.php');
}
$controller->$action();
}
So, you pass $controller as an argument to that function. Thats correct. But then you assign $controller = new MainController(); so $controller is no longer the string you passed to the function, but now ins an object of the class MainController. So you loose your value on what you passed to the function. And then only 1 Line after you do:
if($controller == 'main') {
This will never be true. At this point $controller is an object of your mainController() and the argument will always evaluate to false, so you'll always load the topic_model.php Since your topic() function is inside the MainController() its okay, but its not what MVC is for. Thats just.. some random code there. Thats not MVC, nor good practice.
But well, I don't know what you want to do there with your main controller, I'm not going to dive more into that topic. With the changes of your foreach-loop the call should work and your view should be loaded.
You don't want something like a MainController that is always laoded, or at least not for those methods you have inside - May look up some tutorials on MVC. You only wanna load the controller for the specific section you're in.
Anyway, I wish you all the best for the future and happy coding! :)
I'm working on a similar thing as this one. But I'm trying to assign button either "Join" or "Enter" based on if someone joined the group. The problem is that I'm not sure how I can pass the variable from the category ID ($cats_id) to the view file.
I created a function in the model that checks if the row exists and returns true.
// check if joined the group
public static function checkIfJoined($cats_id)
{
$database = DatabaseFactory::getFactory()->getConnection();
$users_id = Session::get('user_id');
$sql = "SELECT cats_id,users_id FROM categories_joined WHERE users_id = :users_id AND cats_id = :cats_id";
$query = $database->prepare($sql);
$query->execute(array(':users_id' => $users_id, ':cats_id' => $cats_id));
// fetchAll() is the PDO method that gets all result rows
if ($query->rowCount() >= 1 || Session::get('user_account_type') == 7) {
return true;
}
}
Then in Controller I render the model to the view.
public function index()
{
$cats_id = ""; // this doesn't work right obviously
$this->View->render('dashboard/index', array(
'categories' => DashboardModel::getAllCategories(),
'joined' => DashboardModel:: checkIfJoined($cats_id)
));
}
in the view I pass the variable from the preview function 'categories'.
<?php if ($this->categories) { ?>
<?php foreach($this->categories as $key => $value) { ?>
...
<?php $cats_id = $value->cat_id; if ( $this->joined == true ): ?>Enter
<?php else: ?>Join
<?php endif; ?>
You can never pass anything from view to controller because view is parsed after controller.
What you can do here is use model directly by calling DashboardModel::checkIfJoined($cats_id) in your view but that's not perfect approach.
It'll be better to prepare that data in the controller and then pass it to view.
Example controller
public function index()
{
$this->View->render('dashboard/index', array(
'categories' => DashboardModel::getAllCategories(),
'userCategories' => DashboardModel::getUserCategories()
));
}
Example view
<?php
if ($this->categories) {
foreach ($this->categories as $key => $value) {
if (in_array($value->id, $this->userCategories) {
echo 'Joined';
} else {
echo 'Join';
}
}
?>
In this example DashboardModel::getUserCategories() should return results from SELECT cats_id FROM categories_joined WHERE users_id = :users_id.
Actually,
as you see below code,
in model two functions are calling
$this->sendMailtoTutor(),$this->sendMailtoLearner()
i want to check a condition in model that if that condition will true then only these both function will call otherwise not. Is there any way to pass attributes or variable so that i can check condition in aftersave().
my code is as below
in controller
public function actionBooking()
{
$booking_temp = new BookingTemp();
$this->performAjaxValidation($booking_temp);
if (Yii::app()->request->isPostRequest && Yii::app()->request->getPost('BookingTemp'))
{
$booking_temp->attributes = Yii::app()->request->getPost('BookingTemp');
//echo '<pre>';print_r($booking_temp->attributes);exit;
if ($booking_temp->validate())
{
$extra_price = 0;
$post_data = Yii::app()->request->getPost('BookingTemp');
$cam = Cam::model()->findByPk($post_data['temp_cam_id']);
$data = array();
$data = $post_data;
$data['temp_book_user_id'] = Yii::app()->user->id;
$data['temp_book_cam_price'] = $cam->cam_price;
$data['temp_book_duration'] = $cam->cam_duration;
if ($post_data['temp_book_session'] == 2) {
$data['temp_book_cam_price'] = 2 * $cam->cam_price;
$data['temp_book_duration'] = 2 * $cam->cam_duration;
}
if ($post_data['temp_book_is_extra'] == "Y") {
$extra_price = $cam->camExtras->extra_price;
$data['temp_book_extra_price'] = $extra_price;
}
$price_calculation = CamBooking::price_calculation(Yii::app()->user->country_id, $data['temp_book_cam_price'], $extra_price);
$data['temp_book_processing_fees'] = $price_calculation['processing_fees'];
$data['temp_book_service_tax'] = $price_calculation['service_tax'];
$data['temp_book_total_price'] = $price_calculation['total_price'];
$booking_temp->temp_value = serialize($data);
$booking_temp->user_id = Yii::app()->user->id;
$booking_temp->tutor_id = $cam->tutor_id;
$booking_temp_variable = 'check_aftersave';
$booking_temp->save(false, $booking_temp_variable);
//$booking_temp->saveAttributes(array('tutor_id', 'user_id', 'temp_value'));
$created_at = Yii::app()->localtime->fromUTC($booking_temp->created_at);
$created_at_time = strtotime($created_at);
$end_time = $created_at_time + (60 * 3); // 3 min greater from created
$end_time_format = date("Y/m/d H:i:s", $end_time);
echo json_encode(array(
'status' => 'success',
'temp_guid' => $booking_temp->temp_guid,
'end_time_format' => $end_time_format,
), JSON_UNESCAPED_SLASHES);
Yii::app()->end();
} else {
$error = CActiveForm::validate($booking_temp);
if ($error != '[]')
echo $error;
Yii::app()->end();
}
}
}
in model
protected function afterSave()
{
if ($this->isNewRecord)
{
$this->sendMailtoTutor();
$this->sendMailtoLearner();
if ($this->is_message == 'Y' && !empty($this->book_message))
{
Message::insertMessage($this->book_message, $this->book_user_id, $this->cam->tutor_id, $this->cam_id);
}
$user_profile_link = CHtml::link($this->bookUser->fullname, array("/site/user/profile", "slug" => $this->bookUser->slug));
$cam_link = CHtml::link($this->cam->cam_title, array("/site/cam/view", "slug" => $this->cam->slug));
$message = "You have a new booking from {$user_profile_link} for your {$cam_link}";
Notification::insertNotification($this->cam->tutor_id, $message, 'book', $this->book_id);
}
return parent::afterSave();
}
How can I perform this?
Hi See if you want to do it in the afterSave() of BookingTemp Model;. Then you can define a variable in that model like
like
class BookingTemp extends CActiveRecord
{
public $booking_temp_variable;
............
}
now assign this variable before saving your model in actionBooking();
as
$booking_temp->booking_temp_variable = 'check_aftersave';
$booking_temp->save(false);// no need to pass a varible
now in your aftersave function you can easily get it like
protected function afterSave()
{
if ($this->isNewRecord)
{
$this->booking_temp_variable; // this has your value
}
return parent::afterSave();
}
Don't forget to keep it in rules as safe
public function rules(){
// your rules
array('booking_temp_variable','safe');
}
What exacly you want to do?
At first you have to know, that when you are calling save() method and u pass there two args - false and, $booking_temp_variable . The first arg says that you do not run validation, the second one is (should be) array of attributes.
http://www.yiiframework.com/doc/api/1.1/CActiveRecord#save-detail
I do not know how to set a callback function for the view record page in codeigniter.
I use the callback_column function and it does what I need in the grid view, but on the view record page it does not work.
I searched their site and forum and did not found anything that could help me.
My code looks like:
$zeus = new grocery_CRUD();
$zeus->set_theme('bootstrap');
// $zeus->set_language('romanian');
$zeus->set_table('programari');
$zeus->columns(array('id_client', 'id_sala', 'denumire', 'numar_persoane', 'observatii'));
$zeus->callback_column('id_sala',array($this,'_test_function'));
$cod = $zeus->render();
$this->_afiseaza_panou($cod);
public function _test_function($row, $value)
{
return '0';
}
write this lines in \libraries\Grocery_CRUD.php
at line number 3530
protected $callback_read_field = array();
than put this function after constructor call
public function callback_read_field($field, $callback = null)
{
$this->callback_read_field[$field] = $callback;
return $this;
}
//Now update this function to manage the field outputs using callbacks if they are defined for the same
protected function get_read_input_fields($field_values = null)
{
$read_fields = $this->get_read_fields();
$this->field_types = null;
$this->required_fields = null;
$read_inputs = array();
foreach ($read_fields as $field) {
if (!empty($this->change_field_type)
&& isset($this->change_field_type[$field->field_name])
&& $this->change_field_type[$field->field_name]->type == 'hidden') {
continue;
}
$this->field_type($field->field_name, 'readonly');
}
$fields = $this->get_read_fields();
$types = $this->get_field_types();
$input_fields = array();
foreach($fields as $field_num => $field)
{
$field_info = $types[$field->field_name];
if(isset($field_info->db_type) && ($field_info->db_type == 'tinyint' || ($field_info->db_type == 'int' && $field_info->db_max_length == 1))) {
$field_value = $this->get_true_false_readonly_input($field_info, $field_values->{$field->field_name});
} else {
$field_value = !empty($field_values) && isset($field_values->{$field->field_name}) ? $field_values->{$field->field_name} : null;
}
if(!isset($this->callback_read_field[$field->field_name]))
{
$field_input = $this->get_field_input($field_info, $field_value);
}
else
{
$primary_key = $this->getStateInfo()->primary_key;
$field_input = $field_info;
$field_input->input = call_user_func($this->callback_read_field[$field->field_name], $field_value, $primary_key, $field_info, $field_values);
}
switch ($field_info->crud_type) {
case 'invisible':
unset($this->read_fields[$field_num]);
unset($fields[$field_num]);
continue;
break;
case 'hidden':
$this->read_hidden_fields[] = $field_input;
unset($this->read_fields[$field_num]);
unset($fields[$field_num]);
continue;
break;
}
$input_fields[$field->field_name] = $field_input;
}
return $input_fields;
}
than call same as other callback functions
As far as I'm aware GroceryCRUD doesn't provide callbacks or another means of overriding the default output in the view state.
The solution to customising this would be to create a custom view to which you will insert the data from your record. This way you can customise the layout and other presentation.
What you would then do is unset the default read view with:
$crud->unset_read();
And add a new action where there are details on how to do this here.
What to do with the new action is point it to a URL that you map in routes.php if necessary and handle it with a new function in your controller. You'll either have to write a model function to retrieve the data since this isn't passed from GC or you can use the action to target a callback and feed $row to it via POST or something so that the data for the record is accessible in the view. (Look at the example in the link above).
Let's say I have a class...
class A {
private $action;
private $includes;
public function __construct($action, $file) {
//assign fields
}
public function includeFile()
include_once($this->file);
}
$a = new A('foo.process.php', 'somefile.php');
$a->includeFile();
As you can see, includeFile() calls the include from within the function, therefore once the external file is included, it should technically be inside of the function from my understanding.
After I've done that, let's look at the file included, which is somefile.php, which calls the field like so.
<form action=<?=$this->action;?> method="post" name="someForm">
<!--moar markup here-->
</form>
When I try to do this, I receive an error. Yet, in a CMS like Joomla I see this accomplished all the time. How is this possible?
Update
Here's the error I get.
Fatal error: Using $this when not in object context in /var/www/form/form.process.php on line 8
Update 2
Here's my code:
class EditForm implements ISave{
private $formName;
private $adData;
private $photoData;
private $urlData;
private $includes;
public function __construct(AdData $adData, PhotoData $photoData, UrlData $urlData, $includes) {
$this->formName = 'pageOne';
$this->adData = $adData;
$this->photoData = $photoData;
$this->urlData = $urlData;
$this->includes = $includes;
}
public function saveData() {
$this->adData->saveData();
$this->photoData->saveData();
}
public function includeFiles() {
if (is_array($this->includes)) {
foreach($this->includes as $file) {
include_once($file);
}
} else {
include_once($this->includes);
}
}
public function populateCategories($parent) {
$categories = $this->getCategories($parent);
$this->printCategories($categories);
}
public function populateCountries() {
$countries = $this->getCountries();
$this->printCountries($countries);
}
public function populateSubCategories() {
//TODO
}
private function getCategories($parent) {
$db = patentionConnect();
$query =
"SELECT * FROM `jos_adsmanager_categories`
WHERE `parent` = :parent";
$result = $db->fetchAll(
$query,
array(
new PQO(':parent', $parent)
)
);
return $result;
}
private function getCountries() {
$db = patentionConnect();
$query =
"SELECT `fieldtitle` FROM `jos_adsmanager_field_values`
WHERE fieldid = :id";
$result = $db->fetchAll(
$query,
array(
new PQO(':id', 29)
)
);
return $result;
}
private function printCountries(array $countries) {
foreach($countries as $row) {
?>
<option value=<?=$row['fieldtitle'];?> >
<?=$row['fieldtitle'];?>
</option>
<?php
}
}
private function printCategories(array $categories) {
foreach($categories as $key => $row){
?>
<option value=<?=$row['id'];?>>
<?=$row['name'];?>
</option>
<?php
}
}
}
And the include call (which exists in the same file):
$template = new EditForm(
new AdData(),
new PhotoData(),
new UrlData($Itemid),
array(
'form.php',
'form.process.php'
)
);
$template->includeFiles();
And the main file which is included...
if ($this->formName == "pageOne") {
$this->adData->addData('category', $_POST['category']);
$this->adData->addData('subcategory', $_POST['subcategory']);
} else if ($this->formName == "pageTwo") {
$this->adData->addData('ad_Website', $_POST['ad_Website']);
$this->adData->addData('ad_Patent', $_POST['ad_Patent']);
$this->adData->addData('ad_Address', $_POST['ad_Address']);
$this->adData->addData('email', $_POST['email']);
$this->adData->addData('hide_email', $_POST['hide_email']);
$this->adData->addData('ad_phone', $_POST['ad_phone']);
$this->adData->addData('ad_Protection', $_POST['ad_Protection']);
$this->adData->addData('ad_Number', $_POST['ad_Number']);
$this->adData->addData('ad_Country', $_POST['ad_Country']);
$this->adData->addData('ad_issuedate', $_POST['issuedate'] . '/' . $_POST['issuemonth'] . '/' . $_POST['issueyear']);
} else if ($this->formName == "pageThree") {
$this->adData->addData('name', $_POST['name']);
$this->adData->addData('ad_Background', $_POST['ad_Background']);
$this->adData->addData('ad_opeartion', $_POST['ad_operation']);
$this->adData->addData('ad_advlimit', $_POST['ad_advlimit']);
$this->adData->addData('ad_status', $_POST['ad_status']);
$this->adData->addData('ad_addinfo', $_POST['ad_addinfo']);
$this->adData->addData('ad_description', $_POST['ad_description']);
$this->adData->addData('tags', $_POST['tags']);
$this->adData->addData('videolink', $_POST['videolink']);
} else if ($this->formName == "pageFour") {
foreach($_POST['jos_photos'] as $photo) {
$this->photoData->addData(
array(
'title' => $photo['title'],
'url' => $photo['url'],
'ad_id' => $this->photoData->__get('ad_id'),
'userid' => $this->photoData->__get('userid')
)
);
}
}
Update
Strange: while the error itself hadn't been quite related to what the problem was, I found that it was simply an undefined field which I hadn't implemented.
Consider this thread solved. To those who replied, I certainly appreciate it regardless.
This should work. Are you sure you're doing the include from a non-static method that's part of the class (class A in your example)? Can you post the exact code you're using?
Edit: As general advice for problems like this, see if you can trim down the code so the problem is reproducible in a short, simple example that anyone could easily copy/paste to reproduce the exact error. The majority of the time, you'll figure out the answer yourself in the process of trying to simplify. And if you don't, it will make it much easier for others to help you debug.