I have built a CRM that manage leads
I have a table called leads, and in the controller in index() method , I made a request to google API to get the data from my sheet table.
now what's is happen, that in every page refresh i use updateOrCreate() to update the table
and show it in the leads index view with dataTable()
my problem is as I mentioned above, that every page refresh it calling the method to google API,
and it's a performance issue that gets to me in the long run when it is thousand of records
and my question is if there is a way to listen to the sheet table if made changes (edit or added row)
and updated only in this situation
I have thought about to do another table to the sheet data but I need it updated somehow
I need guidelines for how and if I can to do so,
or there is a better way to it.
public function index(Request $request, Lead $lead)
{
$client = new Google_Client();
putenv('GOOGLE_APPLICATION_CREDENTIALS=../att-sheets-b5343f28dd39.json');
$client->useApplicationDefaultCredentials();
$client->addScope(Google_Service_Drive::DRIVE);
$driveService = new Google_Service_Drive($client);
// List Files
// $response = $driveService->files->listFiles();
// Set File ID and get the contents of your Google Sheet
$fileID = '1okqjGbGDnbzJbXDwZ1A6RHJ3LddyL6fGMZWnq88xUiw';
$response = $driveService->files->export($fileID, 'text/csv', array(
'alt' => 'media'));
$content = $response->getBody()->getContents();
// Create CSV from String
$csv = Reader::createFromString($content, 'r');
$csv->setHeaderOffset(0);
$records = $csv->getRecords();
// Create an Empty Array and Loop through the Records
$newarray = array();
foreach ($records as $value) {
$newarray[] = $value;
}
foreach ($newarray as $data) {
$matchThese = array('email' => $data['your-email']);
Lead::updateOrCreate($matchThese,[
'user_name' => 'admin',
'name' => $data['your-name'],
'tel' => $data['your-tel'],
'source' => 'Google sheets',
'sheet_date' => $data['date'].', '.$data['time'],
])->save();
}
$user = User::all();
if ($request->ajax()) {
$data = Lead::where('deleted', '!=' , '1')->orWhereNull('deleted')->latest()->get();
return Datatables::of($data)
->addIndexColumn()
->addColumn('action', function($lead){
$btnEdit = '';
$btnDel = '';
if(auth()->user()->can('update', $lead))
{
$btnEdit = '<i class="glyphicon glyphicon-edit"></i> Edit';
}
if(auth()->user()->can('delete', $lead))
{
$btnDel = '<i class="glyphicon glyphicon-remove"></i> Delete';
}
$btnShow = 'View';
$btn = $btnEdit . $btnDel . $btnShow;
return $btn;
})
->addColumn('checkbox', function($lead)
{
$checkbox = '';
if(auth()->user()->can('delete', $lead))
{
$checkbox = '<input type="checkbox" name="leads_checkbox[]" class="leads_checkbox" value="'.$lead->id.'">';
return $checkbox;
}
})
->rawColumns(['action','checkbox'])
->make(true);
}
return view('leads.index', compact(
['user', 'lead'])
);
}
thanks for the help!!!
Related
I want to save the same data with 365 records within one table. I'm new to Laravel.
I've tried with replicate() but was unsuccessful. I tried this on the Apache server and used Laravel5.7.
my controller
public function price_save(Request $request) {
$price=new Price();
$price->price=$request->price;
$price->extra_bed=$request->extra_bed;
$price->room_id=$request->room;
$id=$request->room;
$price = Price::find($id);
if(null !== $price){
$new = $price->replicate();
if(null !== $new){
$new->push();
// $price->save();
}
I am NOT sure about your code, But you can customize it as per your needs, To just get idea :
$model = User::find($id);
$model->load('invoices');
$newModel = $model->replicate();
$newModel->push();
foreach($model->getRelations() as $relation => $items){
foreach($items as $item){
unset($item->id);
$newModel->{$relation}()->create($item->toArray());
}
}
Credits
public function price_save(Request $request, int $id)
{
if ($id > 365) {
return;
}
$price = new Price();
$price->price = $request->price;
$price->extra_bed = $request->extra_bed;
$price->room_id = $request->room;
$price->save();
$existing = Price::find($request->room);
if ($existing) {
$request = $request->replace([
'price' => $price->price,
'extra_bed' => $price->extra_bed,
'room_id' => $price->room,
]);
}
return price_save($request, $id++);
}
hi i have developed my project in Laravel 4.2 version and i have an array of record and i want to insert this data into database using built-in insert() function but i want to update those entries which are already inserted otherwise insert the record. Can anyone help me
here is my sample code
public static function followAllUsers($user_data) {
$responce = array();
$data = array();
foreach ($user_data['following_id'] as $key => $value) {
$following = UserBussinessLogic::checkAndValidateUser($value);
if ($following != true) {
$responce = Utility::Responce('invalid_user', FALSE, $value);
break;
} else {
if (FriendBussinessLogic::isAlreadyFollowed($user_data['id'], $value)) {
continue;
}
$data[] = array('follower_id' => $user_data['id'], 'following_id' => $value, 'created_at' => date('Y-m-d H:i:s'));
$followData['notifyAbleUsers'][] = $value;
}
}
if ($following) {
if (!empty($data)) {
if (Friend::insert($data)) {
$followData['created_at'] = date('Y-m-d H:i:s');
$followData['follower_id'] = $user_data['id'];
$responce = Utility::Responce('friend_followed', TRUE, $followData);
} else {
$responce = Utility::Responce('general_error', FALSE);
}
} else {
$responce = Utility::Responce('already_followed', TRUE);
}
}
return $responce;
}
Thank you
A little lesser known function that is also available in Laravel 4.2 is:
updateOrCreate
Here's an example on how to use it:
// If there's a flight from Oakland to San Diego, set the price to $99.
// If no matching model exists, create one.
$flight = App\Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99]
);
I am using Laravel 5.2 Backpack in my new project where I have a select_from_array field in my form, depending upon the selected value I want data to be displayed in another select_from_array field. Don't know how to do that. Please help me with this. This is my code
Controller.php
public function __construct()
{
if (Request::segment(3) == 'create') {
$parentField1 = [
'name' => 'cat_id',
'label' => 'Category',
'type' => 'select_from_array',
'options' => $this->categories(),
'allows_null' => false,
];
$parentField = [
'name' => 'subCat_id',
'label' => 'SubCategory',
'type' => 'select_from_array',
'options' => $this->subcategories(),
'allows_null' => false,
];
array_unshift($this->crud['fields'], $parentField1,$parentField);
}
public function categories()
{
$cat = Request::get('cat_id');
$currentId = 0;
if (Request::segment(4) == 'edit' and is_numeric(Request::segment(3))) {
$currentId = Request::segment(3);
}
$entries = Category::where('translation_lang', config('app.locale'))->where('parent_id',0)->orderBy('lft')->get();
if (is_null($entries)) {
return [];
}
$tab = [];
$tab[0] = 'Root';
foreach ($entries as $entry) {
if ($entry->id != $currentId) {
$tab[$entry->translation_of] = '- ' . $entry->name;
}
}
return $tab;
}
public function subcategories()
{
$currentId = 0;
if (Request::segment(4) == 'edit' and is_numeric(Request::segment(3))) {
$currentId = Request::segment(3);
}
$entries = Category::where('translation_lang', config('app.locale'))->where('parent_id','!=' ,0)->orderBy('lft')->get();
if (is_null($entries)) {
return [];
}
$tab = [];
$tab[0] = 'Root';
foreach ($entries as $entry) {
if ($entry->id != $currentId) {
$tab[$entry->translation_of] = '- ' . $entry->name;
}
}
return $tab;
}
I want the id of selected option in the subcategories() where I can use the id to get the data.
I think the best way for you is to create a custom field type for this particular purpose, that includes both selects. Follow this procedure. Start from the select2.blade.php file and add the javascript you need to achieve your goal (on change event on first select2, change the options in the next select2).
I am trying to pass a form data like name, email from simple html page to a CodeIgniter application.
Direcotry Structute:
SampleDir
CodeIgniterApp
Form.html
I am trying to pass form (POST) and recieve inside the CodeIgniter. I am new to CodeIgniter and trying to connect my app to third party app. From what I searched CodeIgniter has controllers and views. Controllers being called first which inturn load up the view.
I tried
$view = array (
'available_services' => $available_services,
'available_providers' => $available_providers,
'company_name' => $company_name,
'manage_mode' => $manage_mode,
'appointment_data' => $appointment,
'provider_data' => $provider,
'customer_data' => $customer,
'post_data' => json_decode($_POST)
);
and passing it to view, but it does not shows up.
HTML Code:
<form action="/appointment" method="POST" target="_blank">
<div style="display:none!important;">
<input type="text" placeholder="name" name="name" id="name" ng-model="cust.name">
<input type="text" placeholder="email" name="email" id="email" ng-model="cust.email">
<input type="text" placeholder="telephone" name="phone" id="phone" ng-model="cust.phone">
</div>
<div class="text-center btn-toolbar" style="margin-top: 30px;">
<button class="btn btn-primary" ng-click="cancel()" style="font-size: 20px;">OK</button>
<button type="submit" name="process" class="btn btn-success" style="font-size: 20px;">Schedule a Call</button>
</div>
</form>
Controller Code:
public function index($appointment_hash = '') {
// echo $this->input->post('email');
var_dump($_SERVER['REQUEST_METHOD']);
if (!$this->check_installation()) return;
$this->load->model('appointments_model');
$this->load->model('providers_model');
$this->load->model('services_model');
$this->load->model('customers_model');
$this->load->model('settings_model');
if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST') {
try {
$available_services = $this->services_model->get_available_services();
$available_providers = $this->providers_model->get_available_providers();
$company_name = $this->settings_model->get_setting('company_name');
// If an appointment hash is provided then it means that the customer
// is trying to edit a registered appointment record.
if ($appointment_hash !== ''){
// Load the appointments data and enable the manage mode of the page.
$manage_mode = TRUE;
$results = $this->appointments_model->get_batch(array('hash' => $appointment_hash));
if (count($results) === 0) {
// The requested appointment doesn't exist in the database. Display
// a message to the customer.
$view = array(
'message_title' => $this->lang->line('appointment_not_found'),
'message_text' => $this->lang->line('appointment_does_not_exist_in_db'),
'message_icon' => $this->config->item('base_url')
. '/assets/img/error.png'
);
$this->load->view('appointments/message', $view);
return;
}
$appointment = $results[0];
$provider = $this->providers_model->get_row($appointment['id_users_provider']);
$customer = $this->customers_model->get_row($appointment['id_users_customer']);
} else {
// The customer is going to book a new appointment so there is no
// need for the manage functionality to be initialized.
$manage_mode = FALSE;
$appointment = array();
$provider = array();
$customer = array();
}
// Load the book appointment view.
$view = array (
'available_services' => $available_services,
'available_providers' => $available_providers,
'company_name' => $company_name,
'manage_mode' => $manage_mode,
'appointment_data' => $appointment,
'provider_data' => $provider,
'customer_data' => $customer,
'post_data' => json_decode($_POST)
);
} catch(Exception $exc) {
$view['exceptions'][] = $exc;
}
$this->load->view('appointments/book', $view);
} else {
// The page is a post-back. Register the appointment and send notification emails
// to the provider and the customer that are related to the appointment. If google
// sync is enabled then add the appointment to the provider's account.
try {
$post_data = json_decode($_POST['post_data'], true);
$appointment = $post_data['appointment'];
$customer = $post_data['customer'];
if ($this->customers_model->exists($customer))
$customer['id'] = $this->customers_model->find_record_id($customer);
$customer_id = $this->customers_model->add($customer);
$appointment['id_users_customer'] = $customer_id;
$appointment['id'] = $this->appointments_model->add($appointment);
$appointment['hash'] = $this->appointments_model->get_value('hash', $appointment['id']);
$provider = $this->providers_model->get_row($appointment['id_users_provider']);
$service = $this->services_model->get_row($appointment['id_services']);
$company_settings = array(
'company_name' => $this->settings_model->get_setting('company_name'),
'company_link' => $this->settings_model->get_setting('company_link'),
'company_email' => $this->settings_model->get_setting('company_email')
);
// :: SYNCHRONIZE APPOINTMENT WITH PROVIDER'S GOOGLE CALENDAR
// The provider must have previously granted access to his google calendar account
// in order to sync the appointment.
try {
$google_sync = $this->providers_model->get_setting('google_sync',
$appointment['id_users_provider']);
if ($google_sync == TRUE) {
$google_token = json_decode($this->providers_model
->get_setting('google_token', $appointment['id_users_provider']));
$this->load->library('google_sync');
$this->google_sync->refresh_token($google_token->refresh_token);
if ($post_data['manage_mode'] === FALSE) {
// Add appointment to Google Calendar.
$google_event = $this->google_sync->add_appointment($appointment, $provider,
$service, $customer, $company_settings);
$appointment['id_google_calendar'] = $google_event->id;
$this->appointments_model->add($appointment);
} else {
// Update appointment to Google Calendar.
$appointment['id_google_calendar'] = $this->appointments_model
->get_value('id_google_calendar', $appointment['id']);
$this->google_sync->update_appointment($appointment, $provider,
$service, $customer, $company_settings);
}
}
} catch(Exception $exc) {
$view['exceptions'][] = $exc;
}
// :: SEND NOTIFICATION EMAILS TO BOTH CUSTOMER AND PROVIDER
try {
$this->load->library('Notifications');
$send_provider = $this->providers_model
->get_setting('notifications', $provider['id']);
if (!$post_data['manage_mode']) {
$customer_title = $this->lang->line('appointment_booked');
$customer_message = $this->lang->line('thank_you_for_appointment');
$customer_link = $this->config->item('base_url') . '/index.php/appointments/index/'
. $appointment['hash'];
$provider_title = $this->lang->line('appointment_added_to_your_plan');
$provider_message = $this->lang->line('appointment_link_description');
$provider_link = $this->config->item('base_url') . '/index.php/backend/index/'
. $appointment['hash'];
} else {
$customer_title = $this->lang->line('appointment_changes_saved');
$customer_message = '';
$customer_link = $this->config->item('base_url') . '/index.php/appointments/index/'
. $appointment['hash'];
$provider_title = $this->lang->line('appointment_details_changed');
$provider_message = '';
$provider_link = $this->config->item('base_url') . '/index.php/backend/index/'
. $appointment['hash'];
}
$this->notifications->send_appointment_details($appointment, $provider,
$service, $customer,$company_settings, $customer_title,
$customer_message, $customer_link, $customer['email']);
if ($send_provider == TRUE) {
$this->notifications->send_appointment_details($appointment, $provider,
$service, $customer, $company_settings, $provider_title,
$provider_message, $provider_link, $provider['email']);
}
} catch(Exception $exc) {
$view['exceptions'][] = $exc;
}
// :: LOAD THE BOOK SUCCESS VIEW
$view = array(
'appointment_data' => $appointment,
'provider_data' => $provider,
'service_data' => $service,
'company_name' => $company_settings['company_name']
);
} catch(Exception $exc) {
$view['exceptions'][] = $exc;
}
$this->load->view('appointments/book_success', $view);
}
}
$this->load->view('appointments/book', $view);
To be more precise, this the the app I am trying to connect to https://github.com/alextselegidis/easyappointments
If the root src folder is appointment, then http://localhost/appointment takes me to appointment/application/views/appointments/book.php and appointment/application/controllers/appointments.php
Have a look and suggest what to do.
I have this trouble too, you have to add this line on your code:
$_POST = json_decode(file_get_contents("php://input"), true);
that would let you use json on code igniter post so after that line you can do
$this->input->post('yourkey')
and you will get the things you want :)
I am trying to get the Image URL of the products by editing the Magento's API items() function. I have used $product-> getImageUrl() to get the URL but I am getting wrong URL.
The URL that I am getting is of the default Image which we place for the products which do not have image(Image Comming Soon like Image's url).
I am calling the function from Android Client using XML-RPC.
I am getting other details of the product correct,but the URL that I am getting for the products is wrong. And, all the URLs of the different products I am getting are same.
FYI, The URL that I am getting in the response is like :
http://192.168.1.237/machinetest/media/catalog/product/cache/0/image/265x/9df78eab33525d08d6e5fb8d27136e95/images/catalog/product/placeholder/image.jpg
The function that I am editing is as followed :
public function items($filters = null, $store = null)
{
$collection = Mage::getModel('catalog/product')->getCollection()
->addStoreFilter($this->_getStoreId($store))
->addAttributeToSelect('name');
if (is_array($filters)) {
try {
foreach ($filters as $field => $value) {
if (isset($this->_filtersMap[$field])) {
$field = $this->_filtersMap[$field];
}
$collection->addFieldToFilter($field, $value);
}
} catch (Mage_Core_Exception $e) {
$this->_fault('filters_invalid', $e->getMessage());
}
}
$result = array();
foreach ($collection as $product) {
//$result[] = $product->getData();
$result[] = array( // Basic product data
'product_id' => $product->getId(),
'sku' => $product->getSku(),
'name' => $product->getName(),
'set' => $product->getAttributeSetId(),
'type' => $product->getTypeId(),
'category_ids'=> $product->getCategoryIds(),
'url_path' => $product-> getImageUrl() // Added the Method here
);
}
return $result;
}
Just write that please try this way..you will get the Solution on the Top
You can able to get Images using this code just go through it and you will get images
public function items($filters = null, $store = null)
{
$collection = Mage::getModel('catalog/product')->getCollection()
->addStoreFilter($this->_getStoreId($store))
->addAttributeToSelect('name');
if (is_array($filters)) {
try {
foreach ($filters as $field => $value) {
if (isset($this->_filtersMap[$field])) {
$field = $this->_filtersMap[$field];
}
$collection->addFieldToFilter($field, $value);
}
} catch (Mage_Core_Exception $e) {
$this->_fault('filters_invalid', $e->getMessage());
}
}
$result = array();
foreach ($collection as $product) {
// $result[] = $product->getData();
$_product = Mage::getModel('catalog/product')->load($product->getId());
$_image=$_product->getImageUrl();
$result[] = array( // Basic product data
'product_id' => $product->getId(),
'sku' => $product->getSku(),
'name' => $product->getName(),
'set' => $product->getAttributeSetId(),
'type' => $product->getTypeId(),
'category_ids'=> $product->getCategoryIds(),
'image_url_path' => $_image
);
}
return $result;
}
hope it's work
if you have any queries tell me i will help you!
I was working with images recently and I believe I have pretty good understanding about it.
I don't think what Josua said is the "real" correct answer. It is good that his answer can solve your problem but I just couldn't stand seeing misleading information.
As for his first option, it is "correct".
Let me break down the code:
Mage_Catalog_Model_Product_Media_Config
public function getMediaUrl($file)
{
$file = $this->_prepareFileForUrl($file);
if(substr($file, 0, 1) == '/') {
return $this->getBaseMediaUrl() . $file;
}
return $this->getBaseMediaUrl() . '/' . $file;
}
public function getBaseMediaUrl()
{
return Mage::getBaseUrl('media') . 'catalog/product';
}
protected function _prepareFileForUrl($file)
{
return str_replace(DS, '/', $file);
}
As you can see, it just simply add media/ + catalog/product + $file.
$file is taken from database, the value will be something like /e/x/example.jpeg
Your uploaded product images are stored inside those folders.
Now, for the problem why $product-> getImageUrl() give you wrong URL is still unknown.
The code that Josua suggest for second option:
$this->helper('catalog/image')
->init($product, $type)
->resize(163, 100);
is "almost" the same with $product->getImageUrl(), it just have difference in resize
Mage_Catalog_Model_Product
public function getImageUrl()
{
return (string)$this->_getImageHelper()->init($this, 'image')->resize(265);
}
So for his second option, it will give the same result with your old code.
I don't know why did he suggest the second option, I think he never check what is behind those functions (not a good idea as it can lead to wrong information)
When you call for $product->getImageUrl(), it will try to load your image from cache if it exists, if not, it will load the image from database (for the path and then will look for your correct image from media folder) and create the cache. If it is unable to find the image or an error occurred, it will get the placeholder image.
My suggestion is to check if there is an exception thrown. You need to use your old code $product->getImageUrl(). Open your app/code/core/Mage/Catalog/Helper/Image.php
Then go to:
Mage_Catalog_Helper_Image
public function __toString()
{
try {
if( $this->getImageFile() ) {
$this->_getModel()->setBaseFile( $this->getImageFile() );
} else {
$this->_getModel()->setBaseFile( $this->getProduct()->getData($this->_getModel()->getDestinationSubdir()) );
}
if( $this->_getModel()->isCached() ) {
return $this->_getModel()->getUrl();
} else {
if( $this->_scheduleRotate ) {
$this->_getModel()->rotate( $this->getAngle() );
}
if ($this->_scheduleResize) {
$this->_getModel()->resize();
}
if( $this->getWatermark() ) {
$this->_getModel()->setWatermark($this->getWatermark());
}
$url = $this->_getModel()->saveFile()->getUrl();
}
} catch( Exception $e ) {
//put log to show error message
Mage::log($e->getMessage());
$url = Mage::getDesign()->getSkinUrl($this->getPlaceholder());
}
return $url;
}
Put Mage::log($e->getMessage()); to log if there is an exception thrown. Most likely your placeholder image is called because there was an exception thrown.
It is just a suggestion from me to ensure there is nothing's wrong with your image / other things as in fact you have solved your problem by directly get the image from media/catalog/product/...
Another correction for Josua's code:
Notice the $full_product = Mage::getModel('catalog/product')->load($product_id);
It is absolutely unnecessary since inside foreach($collection as $product), the product object will be loaded, so another load of product is unnecessary (also $product_id is undefined)
UPDATE, just fixing your code:
public function items($filters = null, $store = null)
{
$collection = Mage::getModel('catalog/product')->getCollection()
->addStoreFilter($this->_getStoreId($store))
->addAttributeToSelect(array('name','image'));
//->addAttributeToSelect('name'); add another select, either image / small_image / thumbnail, modify it as you need
if (is_array($filters)) {
try {
foreach ($filters as $field => $value) {
if (isset($this->_filtersMap[$field])) {
$field = $this->_filtersMap[$field];
}
$collection->addFieldToFilter($field, $value);
}
} catch (Mage_Core_Exception $e) {
$this->_fault('filters_invalid', $e->getMessage());
}
}
$result = array();
foreach ($collection as $product) {
//$result[] = $product->getData();
$result[] = array( // Basic product data
'product_id' => $product->getId(),
'sku' => $product->getSku(),
'name' => $product->getName(),
'set' => $product->getAttributeSetId(),
'type' => $product->getTypeId(),
'category_ids'=> $product->getCategoryIds(),
'url_path' => $product-> getImageUrl() // Added the Method here
);
}
return $result;
}
Your code was awesome!
Yes, you can get image url with :
'url_path' => Mage::getModel('catalog/product_media_config')
->getMediaUrl($product->getImage());//getSmallImage(), getThumbnail()
or another option by calling :
$type = 'small_image';
'url_path' => $this->helper('catalog/image')
->init($product, $type)
->resize(163, 100);
can be changed by 'image' small_image' or 'thumbnail'
Default:
Base Image: 265x265 pixel
Small Image: 135x135 pixel
Thumbnail Image: 75x75 pixel
The easier option (detailed):
public function items($filters = null, $store = null)
{
$collection = Mage::getModel('catalog/product')->getCollection()
->addStoreFilter($this->_getStoreId($store))
->addAttributeToSelect('name');
if (is_array($filters)) {
try {
foreach ($filters as $field => $value) {
if (isset($this->_filtersMap[$field])) {
$field = $this->_filtersMap[$field];
}
$collection->addFieldToFilter($field, $value);
}
} catch (Mage_Core_Exception $e) {
$this->_fault('filters_invalid', $e->getMessage());
}
}
$result = array();
foreach ($collection as $product) {
//$result[] = $product->getData();
$full_product = Mage::getModel('catalog/product')->load($product_id);
$result[] = array( // Basic product data
'product_id' => $product->getId(),
'sku' => $product->getSku(),
'name' => $product->getName(),
'set' => $product->getAttributeSetId(),
'type' => $product->getTypeId(),
'category_ids'=> $product->getCategoryIds(),
'url_path' => $full_product->getImageUrl(),
// 'product_path' => $full_product->getProductUrl()
// you can call $full_product->getData();
);
}
return $result;
}