I'm programming a web app. The backend is a RESTFul app based in Laravel 4.
I'm having problems with a particular controller.
BedsController.php
class BedsController extends \BaseController {
/**
* Display a listing of the resource.
* GET /beds
*
* #return Response
*/
public function index()
{
//
$user = JWTAuth::parseToken()->authenticate();
$data = Input::get('room');
$retorno = array();
$hoy = date('Y-m-d');
if( $data ){
$d = intval( $data );
$beds = Bed::where('room', '=', $d )->get( array('size', 'room', 'id', 'name') );
foreach( $beds as $b ){
$b->stay = Stay::where('bed', '=', $b->id )
->where('indate', '<=', $hoy )
->where('outdate', '>=', $hoy )
->get( array( 'id', 'room', 'bed', 'guest', 'booking', 'indate', 'outdate' ) );
dd( $b->stay );
if( isset( $b->stay->guest ) ){
$b->stay->huesped = Guest::find( $b->stay->guest );
}else{}
if( isset( $b->stay->booking ) ){
$b->stay->huesped = Booking::find( $b->stay->booking );
}
//dd( $b->stay );
array_push( $retorno, $b );
}
//$room = Room::find( $d );
//return $room->camas()->get( 'size', 'room', 'id');
//$beds = Bed::where('room', $data )->get();
}else{
$beds = Bed::where('hotel', '=', $user->hostel )->get( array('size', 'room', 'id', 'name') );
foreach( $beds as $b ){
$be = $b['attributes'];
$st = array();
$stay = Stay::where('bed', '=', $b->id )
->where('indate', '<=', $hoy )
->where('outdate', '>=', $hoy )
->get( array( 'id', 'room', 'bed', 'guest', 'booking', 'indate', 'outdate' ) );
//return $stay[0];
$st = $stay[0];
//dd( $stay[0] );
if( isset( $stay[0] ) ){
if( $stay[0]['attributes']['guest'] > 0 ){
$be['huesped'] = Guest::find( $b->stay->guest );
}else{}
if( $stay[0]['attributes']['booking'] ){
$be['reserva'] = Booking::find( $b->stay->booking );
}
$be['stay'] = $st;
}
array_push( $retorno, $be);
$be = array();
}
}
return $retorno;
}
So, when I make a call to mysiteapp.local/beds, I should get back a composite array with the bed's data and, if there's a reservation, or if that bed's occupied at the moment, the stay info and guest's info.
But all I get is a compiling error message sayin':
error:{type: "ErrorException", message: "Undefined offset: 0",…}
file:"/home/pablo/htdocs/pbertran/angularh/api/vendor/laravel/framework/src/Illuminate/Support/Collection.php"
line:788
message:"Undefined offset: 0"
type:"ErrorException"
Have been googling around, but couldn't find any solution.
Any ideas?
Thanks in advance!
You make assumptions about that index being present, which may not always be the case. Your logic should be more thussly:
$st = isset($stay[0]) ? $stay[0] : false;
if ($st){
//now you can use it safely.
}
To add another outcome, I was doing a "double" GroupBy on the collection:
$price_change->grouped_lines = $price_change->lines->groupBy('PriceListID')->transform(function($item, $k) {
return $item->groupBy('StockID');
});
The above basically groups the collection by 2 keys so:
$price_change->grouped_lines[PriceListID][StockID]->
I received the "Undefined offset 0 - collection.php" error
To fix it I had to first do a isset() on the first key then the second:
if(isset($price_change->grouped_lines[1]) && isset($price_change->grouped_lines[1][23]))
Related
I have function previously made which get me a set of questions array each time shuffled in a new set of order each time when i take a quiz with shuffle() function
Original array (Q1,Q2,Q3,Q4,Q5,Q6)
1st time it gives me (Q2,Q4,Q1,Q3,Q6,Q5)
2nd time it gives me (Q3,Q4,Q2,Q6,Q1,Q5) and so on.
everytime a new set of questions.
This is the function code working for only for shuffle
/**
* Update user questions.
*
* #param $quiz_id
* #param $course_id
* #param $user_id
*/
public function update_user_questions( $quiz_id, $course_id, $user_id ) {
global $wpdb;
$item = null;
switch ( current_action() ) {
case 'pmi-course/user/quiz-redone':
$item = $wpdb->get_row(
$wpdb->prepare( "
SELECT * FROM {$wpdb->prefix}pmicourse_user_items
WHERE item_id = %d
AND user_id = %d
AND ref_id = %d
ORDER BY user_item_id DESC
", $quiz_id, $user_id, $course_id )
);
break;
case 'pmi-course/user/quiz-started':
break;
}
if ( ! $item ) {
return;
}
if ( ! $item->status == 'started' ) {
return;
}
$random_quiz = get_user_meta( $user_id, 'random_quiz', true );
$quiz = LP_Quiz::get_quiz( $quiz_id );
if ( $quiz && $questions = $quiz->get_questions() ) {
$questions = array_keys( $questions );
shuffle( $questions );
$question_id = reset( $questions );
// set user current question
$user = pmi_course_get_current_user();
$user_course = $user->get_course_data( $course_id );
$item_quiz = $user_course->get_item($quiz_id);
$item_quiz->set_meta( '_current_question', $question_id );
$item_quiz->update_meta();
pmi_course_update_user_item_meta( $item->user_item_id, 'current_question', $question_id );
if ( empty( $random_quiz ) ) {
$random_quiz = array( $quiz_id => $questions );
} else {
$random_quiz[ $quiz_id ] = $questions;
}
update_user_meta( $user_id, 'random_quiz', $random_quiz );
}
}
/**
* Random quiz questions.
*
* #param $quiz_questions
* #param $quiz_id
*
* #return array
*/
public function random_questions( $quiz_questions, $quiz_id ) {
if ( get_post_meta( $quiz_id, '_lp_random_mode', true ) == 'yes' ) {
// get user meta random quiz
$random_quiz = get_user_meta( get_current_user_id(), 'random_quiz', true );
if ( is_admin() || empty( $random_quiz ) || empty( $random_quiz[ $quiz_id ] ) ) {
return $quiz_questions;
}
$questions = array();
if ( array_key_exists( $quiz_id, $random_quiz ) && sizeof( $random_quiz[ $quiz_id ] ) == sizeof( $quiz_questions ) ) {
foreach ( $random_quiz[ $quiz_id ] as $question_id ) {
if ( $question_id ) {
$questions[ $question_id ] = $question_id;
}
}
} else {
$question_ids = array_keys( $quiz_questions );
shuffle( $question_ids );
$random_quiz[ $quiz_id ] = $question_ids;
$questions = array();
foreach ( $question_ids as $id ) {
$questions[ $id ] = $quiz_questions[ $id ];
}
}
return $questions;
}
return $quiz_questions;
}
This is what i tried to pull out specific number of questions randomly like "4" questions out of "6" questions from a set but it gives the random result one time and not again like shuffle() i know array_rand() gives different value each time but why not in my case. may be i am doing something wrong . I have put down both the case either can anyone identify me what i am doing wrong or the solution could be extended to more better. Any help would be appreciated.
Original array (Q1,Q2,Q3,Q4,Q5,Q6)
First time (Q1,Q4,Q5,Q6)
Second time (Q1,Q4,Q5,Q6)
Third time (Q1,Q4,Q5,Q6) ---i want different sets for each time
What i tried to achieve this
///for first function
if ( $quiz && $questions = $quiz->get_questions() ) {
$questions = array_rand( $questions , 4);
$question_id = reset( $questions );
///for second function
if ( array_key_exists( $quiz_id, $random_quiz ) && sizeof( $random_quiz[ $quiz_id ] ) < sizeof( $quiz_questions ) ) {
foreach ( $random_quiz[ $quiz_id ] as $question_id ) {
if ( $question_id ) {
$questions[ $question_id ] = $question_id;
}
}
} else {
question_ids = array_rand( $quiz_questions , 4);
$random_quiz[ $quiz_id ] = $question_ids;
questions = array();
foreach ( $question_ids as $id ) {
$questions[ $id ] = $quiz_questions[ $id ];
}
}
Simple function to grab a set of random elements from an array:
$questions = array("Question 1","Question 2","Question 3","Question 4","Question 5","Question 6","Question 7","Question 8","Question 9","Question 10");
function shuffle_questions($questions, $num_questions){
$random_questions = [];
for($i = 0; $i < $num_questions){
$random_num = rand(0, 9);
$random_questions[] = $questions[$random_num];
}
return $random_questions;
}
If you only want it to return unique questions (Probably what you're looking for)
function shuffle_questions($questions, $num_questions){
$questions_temp = $questions;
$random_questions = [];
for ($i = 0; $i++; $i < $num_questions){
$key = array_rand($questions_temp, 1);
$random_questions[] = $questions_temp[$key];
$unset($questions_temp[$key]);
}
return $random_questions;
}
I'm in the process of developing a WordPress plugin. When editing a user's profile page, I need to be able to retrieve the ID of that user (not the currently logged in user).
I'm using the Advanced Custom fields plugin, and using a load filter for the function in question.
add_filter( 'acf/load_field/name=funbotic_parents', 'funbotic_load_parents' );
function funbotic_load_parents( $field ) {
$args = array(
'role' => 'customer',
'orderby' => 'display_name',
'order' => 'ASC',
);
$parent_data_array = get_users( $args );
// Clear choices array in case it was previously set.
$field['choices'] = array();
foreach ( $parent_data_array as $parent ) {
$parent_ID = $parent->ID;
$parent_display_name = $parent->display_name;
$field['choices'][$parent_ID] = $parent_display_name;
}
$current_user = (int) $_GET['user_id'];
$previously_associated_parents = get_user_meta( $current_user_id, 'funbotic_parents' );
if ( empty( $previously_associated_parents ) || is_null( $previously_associated_parents ) ) {
update_user_meta( $current_user_id, 'funbotic_previously_associated_parents', $previously_associated_parents );
} else {
$new_meta = funbotic_clean_array( $previously_associated_parents );
update_user_meta( $current_user_id, 'funbotic_previously_associated_parents', $new_meta );
}
return $field;
}
The line $current_user = (int) $_GET['user_id']; is returning null. Is there a way to pull 'user_id' from the URL? It's not an ideal solution but at this point I'm starting to get desperate. The URL looks like this:
http://dev-funbotic.local/wp-admin/user-edit.php?user_id=115&wp_http_referer=%2Fwp-admin%2Fusers.php%3Fs%3Dtest%26action%3D-1%26new_role%26course_id%26group_id%26paged%3D1%26action2%3D-1%26new_role2
You can try getting the current url and breaking it down to query params like this:
$query = explode('&', $_SERVER['QUERY_STRING']);
$params = array();
if(!empty($query[0])){
foreach( $query as $param ){
list($name, $value) = explode('=', $param, 2);
$params[urldecode($name)][] = urldecode($value);
}
}
then you can access the user_id by $params['user_id'][0]
I'm trying to get the $pi1 and $pi2 variable values inside of the add_custom_price function, but nothing seems to be working.
I have looked at setting variables to be accessible from function classes but I'm not sure I understand how to access them correctly.
add_filter( 'gform_confirmation', array(gravity_pi,custom_confirmation), 10, 4 );
class gravity_pi {
public $pi1;
public $pi2;
public function custom_confirmation( $confirmation, $form, $entry, $ajax, $product_id, $pi1, $pi2 ) {
if( $form['id'] == '2' ) {
$post = get_post( $entry['post_id'] );
$this->pi1 = rgar( $entry, '20' );
$this->pi2 = rgar( $entry, '21' );
$exclude_list = array("pi24","pi64","pi65","pi66","pi67","pi68","pi69","pi70","pi71","pi72","pi73","pi74","pi75","pi76","pi77","pi78","pi79","pi80","pi81","pi82");
if(!in_array($this->pi1, $exclude_list) && !empty($this->pi1)){
$target_product_id = '86';
$pid1 = '86';
}else{
$pid1 = preg_replace("/[^0-9,.]/", "", $this->pi1 );
}
if(!in_array($pi2, $exclude_list) && !empty($this->pi2)){
$target_product_id = '87';
$pid2 = '87';
}else{
$pid2 = preg_replace("/[^0-9,.]/", "", $this->pi2);
}
$product_ids = ''.$pid1.','.$pid2.'';
$url = 'https://*****.com/cart/?add-to-cart='.$product_ids.'';
$confirmation = array( 'redirect' => $url );
}
return $confirmation;
}
public function add_custom_price( $cart_object, $entry,$form, $field, $input_id ) {
foreach ( $cart_object->cart_contents as $key => $value ) {
if( 86 == $value['data']->id ) {
$value['data']->set_price( $this->pi1 );
}
if( 87 == $value['data']->id ) {
$value['data']->set_price( $this->pi2 );
}
}
}
}
add_action( 'woocommerce_before_calculate_totals', array(gravity_pi,add_custom_price));
You need to use $this to get/set any property in the class.
// set pi1 property value
$this->pi1 = 10;
//print/get property value
echo $this->pi1;
When you're setting the class properties (pi1 & pi2) you need to reference them in the same way you access them. Ex.
<?php
...
$this->pi1 = rgar($entry, '20');
Change all references (except where you declare them) of $pid1 to $this->pid1. Do this for $pid2 too.
Check this video out - https://www.youtube.com/watch?v=4c4nP7GLL1c
I would like to know how can I do a SELECT from a Magento core table but not using pure SQL but using collections.
Currently, inside a class that extends Mage_Core_Model_Abstract, on a given function I have the following code:
$resource = Mage::getSingleton("core/resource");
$tableName_SalesQuoteItem = $resource->getTableName("sales/quote_item");
$readConnection = $resource->getConnection("core_read");
$sqlInstruction = "SELECT item_id FROM {$tableName_SalesQuoteItem} WHERE sku = :sku AND quote_id = :quote_id;";
$binds = array("sku" => $itemSku, "quote_id" => $quoteID);
$result = $readConnection->query($sqlInstruction, $binds);
if($row = $result->fetch()) {
$currentItemID = $row["item_id"];
}
Any ideas?
Thanks!
The issue appears to be is that you're trying to load the header table 'sales/quote' and call items on it, when the items are stored in the sub-table sales/quote_item
Here's a functional prototype:
<?php
require_once( 'app/Mage.php' );
umask(0);
Mage::app('default');
$sCustomerId = 1;
$oQuotes = Mage::getModel( 'sales/quote' )->getCollection();
$oQuotes->addFieldToFilter( 'customer_id', $sCustomerId );
foreach( $oQuotes as $oQuote )
{
var_dump( $oQuote->getId() );
var_dump( $oQuote->getData( 'customer_email' ) );
var_dump( $oQuote->getData( 'customer_id' ) );
$oItems = Mage::getModel( 'sales/quote_item' )
->getCollection()
->setQuote( $oQuote );
foreach( $oItems as $oItem )
{
var_dump( $oItem->getData( 'sku' ) );
var_dump( $oItem->getData( 'name' ) );
var_dump( $oItem->getData( 'description' ) );
var_dump( $oItem->getData( 'price' ) );
}
}
$iCountQuotes = $oQuotes->count();
var_dump( $iCountQuotes );
?>
From your question it appears that you are looking for an ORM way to achieve the same thing you are doing with your query.
Here you go:
$collection = Mage::getModel('sales/quote')->getCollection();
$collection->addAttributeToFilter('sku',$itemSku);
$collection->addAttributeToFilter('quote_id',$quoteID);
if($collection->count())
{
//Add your code here
$firstItem = $collection->getFirstItem();
print_r($firstItem);
}
Read more about Magento ORM basics here
You could alternatively try addFieldToFilter if addAttributeToFilter doesn't work.
I have a collection of products in Magento that I would like to be able to get the media gallery images out of. However I am finding that I have to iterate though my collection and load the product again to get the getMediaGalleryImages() function to work properly.
$products = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect('*')
->addAttributeToFilter('visibility', 4)
->addAttributeToFilter('status', 1);
foreach($products as $product) {
$_product = Mage::getModel('catalog/product')->load($product->getId());
$product->getMediaGalleryImages(); // This returns nothing
$_product->getMediaGalleryImages(); // Returns the Collection of Images
}
Obviously I could continue just reloading the product each time, but that would add quite a bit of overhead to the time required to run this code.
Is there a way to add in the media gallery images to the collection?
You can use
$product->load('media_gallery');
before getMediaGalleryImages (on the products you loaded in the collection).
One simple method for future reference:
Outside your foreach add
$mediaBackend = Mage::getModel('catalog/product_attribute_backend_media');
$mediaGalleryAttribute = Mage::getModel('eav/config')->getAttribute(Mage::getModel('catalog/product')->getResource()->getTypeId(), 'media_gallery');
$mediaBackend->setAttribute($mediaGalleryAttribute);
and then do the foreach:
foreach ($productCollection as $product) {
$mediaBackend->afterLoad($product);
}
You will have then the gallery loaded on product.
load product's cached image using collection by following codes
Mage::helper('catalog/image')->init($_product, 'small_image')->resize(135);
//or
Mage::helper('catalog/image')->init($_product, 'thumbnail')->resize(135);
//or
Mage::helper('catalog/image')->init($_product, 'image')->resize(135);
this is the collection which i used
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect('small_image') //or
->addAttributeToSelect('thumbnail') //or
->addAttributeToSelect('image');
You can create a helper class, and use it every time you need media gallery images to be loaded for a collection of products:
class My_Package_Helper_Media extends Mage_Core_Helper_Abstract {
public function addMediaGalleryAttributeToProductCollection( &$productCollection )
{
$storeId = Mage::app()->getStore()->getId();
$ids = array();
foreach ( $productCollection as $product ) {
$ids[] = $product->getEntityId();
}
$resource = Mage::getSingleton( 'core/resource' );
$conn = Mage::getSingleton( 'core/resource' )->getConnection( 'catalog_read' );
$select = $conn->select()
->from(
array( 'mg' => $resource->getTableName( 'catalog/product_attribute_media_gallery' ) ),
array(
'mg.entity_id', 'mg.attribute_id', 'mg.value_id', 'file' => 'mg.value',
'mgv.label', 'mgv.position', 'mgv.disabled',
'label_default' => 'mgdv.label',
'position_default' => 'mgdv.position',
'disabled_default' => 'mgdv.disabled'
)
)
->joinLeft(
array( 'mgv' => $resource->getTableName( 'catalog/product_attribute_media_gallery_value' ) ),
'(mg.value_id=mgv.value_id AND mgv.store_id=' . $storeId . ')',
array()
)
->joinLeft(
array( 'mgdv' => $resource->getTableName( 'catalog/product_attribute_media_gallery_value' ) ),
'(mg.value_id=mgdv.value_id AND mgdv.store_id=0)',
array()
)
->where( 'entity_id IN(?)', $ids );
$mediaGalleryByProductId = array();
$stmt = $conn->query( $select );
while ( $gallery = $stmt->fetch() ) {
$k = $gallery[ 'entity_id' ];
unset( $gallery[ 'entity_id' ] );
if ( !isset($mediaGalleryByProductId[$k]) ) {
$mediaGalleryByProductId[$k] = array();
}
$mediaGalleryByProductId[$k][] = $gallery;
}
unset( $stmt ); // finalize statement
// Updating collection ...
foreach ( $productCollection as &$product ) {
$productId = $product->getEntityId();
if ( isset( $mediaGalleryByProductId[ $productId ] ) ) {
$product->setData( 'media_gallery', array( 'images' => $mediaGalleryByProductId[ $productId ] ) );
}
}
unset( $mediaGalleryByProductId );
}
}
Sample usage:
$coll = Mage::getResourceModel('catalog/product_collection')
->setStoreId( Mage::app()->getStore()->getId() )
->addAttributeToFilter( 'sku', array( 'in' => array( 'AAA', 'BBB' ) ) );
Mage::helper('my_package/media')->addMediaGalleryAttributeToProductCollection( $coll );
Here the code you were looking for, sorry for the delay :)
It come from this discussion:
http://www.magentocommerce.com/boards/viewthread/17414/
I just added some extra check on the number of id a and pagination
function addMediaGalleryAttributeToCollection(Mage_Catalog_Model_Resource_Product_Collection $_productCollection)
{
if (Mage::getStoreConfig('color_selector_plus/colorselectorplusgeneral/showonlist', Mage::app()->getStore())) {
$_mediaGalleryAttributeId = Mage::getSingleton('eav/config')->getAttribute('catalog_product', 'media_gallery')->getAttributeId();
$_read = Mage::getSingleton('core/resource')->getConnection('catalog_read');
$pageCur = $_productCollection->getCurPage();
$pageSize = $_productCollection->getPageSize();
$offset = $pageSize * ($pageCur - 1);
$ids = $_productCollection->getAllIds($pageSize, $offset);
// added check on products number: if 0 ids the following query breaks
if (count($ids) > 0) {
$sql = '
SELECT
main.entity_id, `main`.`value_id`, `main`.`value` AS `file`, `value`.`disabled`,
/*`value`.`label`, `value`.`position`, */
/*`default_value`.`label` AS `label_default`, */
/*`default_value`.`position` AS `position_default`, */
`default_value`.`disabled` AS `disabled_default`
FROM `catalog_product_entity_media_gallery` AS `main`
LEFT JOIN `catalog_product_entity_media_gallery_value` AS `value`
ON main.value_id=value.value_id AND value.store_id=' . Mage::app()->getStore()->getId() . '
LEFT JOIN `catalog_product_entity_media_gallery_value` AS `default_value`
ON main.value_id=default_value.value_id AND default_value.store_id=0
WHERE (
main.attribute_id = ' . $_read->quote($_mediaGalleryAttributeId) . ')
AND (main.entity_id IN (' . $_read->quote($_productCollection->getAllIds()) . '))
/*ORDER BY IF(value.position IS NULL, default_value.position, value.position) ASC */
';
$_mediaGalleryData = $_read->fetchAll($sql);
$_mediaGalleryByProductId = array();
foreach ($_mediaGalleryData as $_galleryImage) {
$k = $_galleryImage['entity_id'];
unset($_galleryImage['entity_id']);
if (!isset($_mediaGalleryByProductId[$k])) {
$_mediaGalleryByProductId[$k] = array();
}
$_mediaGalleryByProductId[$k][] = $_galleryImage;
}
unset($_mediaGalleryData);
foreach ($_productCollection as &$_product) {
$_productId = $_product->getData('entity_id');
if (isset($_mediaGalleryByProductId[$_productId])) {
$_product->setData('media_gallery', array('images' => $_mediaGalleryByProductId[$_productId]));
}
}
unset($_mediaGalleryByProductId);
}
}
return $_productCollection;
}