Omeka: Get all items in Controller - php

I'm writing an Omeka Plugin and wants to get the list of all public Items with their all elements, in a controller under my plugin.
I've tried get_items() but the function doesn't exists, it looks like the function is only available for the views - not sure how.
another try was to manually fetch the records from database, but that's not a standard way.
So, the question is, is there a predefined function/class or way to get all the items in a controller?

I'm not sure if there is a function that will get you the items along with all of their element texts, but if you want a list of items, inside the controller you should be able to make a call like:
$items = $this->_helper->db->getTable('Item')->findAll();
The Omeka docs warn against getting all the items at once because it could be memory intensive. So, alternatively, you can loop through items.
$items = $this->_helper->db->getTable('Item');
$item = $items->findFirst();
while($item != NULL){
// Do something
$item = $items->findNext($item);
}
There is a "public" property on an item that tells you if it's public. In order to get the element texts for an item, I think you'd have to make a query on the ElementText table.
For more information, see the Omeka read the docs page for Table_Item, Omeka_Db_Table and Item:
http://omeka.readthedocs.io/en/latest/Reference/libraries/Omeka/Db/Table.html
http://omeka.readthedocs.io/en/latest/Reference/models/Table/Item.html
http://omeka.readthedocs.io/en/latest/Reference/models/Item.html

Related

Magento 2/Wordpress/Fishpig related posts

I am currently trying to retrieve a list of related posts on the post article page (post single). I have created a new function within /Block/Post/ListPost.php
public function getRelatedPosts()
{
$posts = $this->getPosts();
die($this->getCategoryId());
return $this->_postCollection;
}
However when I try and output getCategoryId, I get nothing. I'm also unsure how I apply a category filter to the post collection.
Can anyone advise here?
I'm not sure where you have got the getCategoryId method from but this is not part of the ListPost block class so will not work. You cannot just invent methods like this.
You should check the block class for what methods are available. An easy way to do that without even loading the file is to add the following PHP to the class:
echo sprintf('<pre>%s</pre>', print_r(get_class_methods($this)));
exit;
You don't specify in what way the posts should be related but I'm guessing you want to get posts from the same category. One option to do this would be to load the primary category of the post and then get a post collection based on this. If you look in the Post class file, you will see the getParentTerm($taxonomy) method.
if ($category = $post->getParentTerm('category')) {
$relatedPosts = $category->getPostCollection();
// Remove the current post from the collection
$relatedPosts->addFieldToFilter('ID', array('neq' => $post->getId()));
}
You should always look at the class file's you're working with. That is the beauty of open source. You can literally see what methods are available for each object and you can even see how they work.

Correct way to handle my URL request

I have an application which I am trying to build using Slim PHP and at the moment I am struggling with one Route I am trying to sort out. Basically what happens is I go to GET /:slug and this provides me with a product view. However if there are variations on this product, it will be an intro page in which a visitor can target an exact product. The differences in these products will be :
Color
Dial
Strap
Material
Possibly a few others. The problem I am having is that I am not 100% sure which if any there will be. Do I write my routes for every possibility? Or is there a way I can get this to take a more relaxed approach to how this is formed?
I saw an example where someone did the following :
$app->get("/:slug(/:dial(/:strap(/:material)))", "Route\To\Controller:Action");
However I am assuming this will require this to be in that set order?
Also a note to add would be that some products have no additional filters and respond directly to /:slug whereas others may require all of the additional filters.
These results are all set in the database. I grab all products that have a similar slug as it equates to the product name, then each filter or collection of filters will be determined by certain parts in the database. For example: /this-product/this-dial/this-color/this-strap/this-material all of these values will be stored within the database table for the product - they either have a corresponding value for material - or it is NULL.
This allows me to on the root URL with the SLUG I can show variations - which will aid in the shopping experience in my opinion.
Does anybody have a solution?? Anyway I could achieve this? Am I going about it the wrong way?
One possible way is to render different templates based on the number of returned products. For example, if you are using Twig Template extension you can easily iterate over the set of results and render two templates one for Product Description and one for Product Group.. Alternatively, You can handle this while rendering a view in your SLIM Route
$app->get('/:slug', function ($slug) use ($app) {
$db = new dbConn();
$Products = $db->ProductQuery(); // DB querying for 'slug' & returned product (s)
if( // here check how many $Products and if = 1 ) {
$app->render('single_product_view.html',$Products);
} else if( /// > 1 ) {
$app->render('multiple_product_view.html',$Products);
} else {
$app->response->redirect($app->urlFor('notFoudnt'), 404); // or whatever other route..
}
})->name("product");
As for the querying why do you want to have a route for each product attribute ?
Can't you in this case have one route for the product view and add a query parameter ( attributes ) to URL
/this-product?dial=this-dial&color=this-color&strap=this-strap&material=this-material
$app->get('/:slug', function ($slug) use ($app) {
$Dial = $app->request()->get('dial');
$Color = $app->request()->get('color');
$Strap = $app->request()->get('strap');
$Mat = $app->request()->get('material');
// same as above, build your query string and render corresponding view
})->name("product");
You can also Group your routes ( for ajax request maybe.. )
$app->group('/api', function () use ($app) {
// Products attributes group route
$app->group('/products', function () use ($app) {
// Get Products with color = :color /api/products/color/:color
$app->get('/color/:color', function ($color ) {
});
// Get Products with Strap = :strap /api/products/strap/:strap
$app->get('/strap/:strap', function ($strap) {
});
// and so on..
});
});

Magento Quote Item object - how can I load item's options?

While I know that I can just load Quote Item Options collection and filter it by item_id, I just can't wrap my mind around that Magento folks haven't added any _afterLoad or _loadOptions method to easily assign the options to an item, since there's already a _options, _optionsByCode properties...
to provide some example of what I'm doing:
// updated (forgot to actually load object
$item = Mage::getModel('sales/quote_item')->load($itemId);
$buyRequest = $item->getBuyRequest(); // almost empty, only qty is set
I want to know if there's some $item->loadOptions() method... or other native way to load options into an item
UPDATE
What I want to do: I want to load item object and use some native way to add its options to this loaded object.
I ended up using next piece of code
/** #var Mage_Sales_Model_Resource_Quote_Item_Option_Collection $options */
$options = Mage::getResourceModel('sales/quote_item_option_collection');
$options->addItemFilter($item->getId());
foreach ($options as $option) {
$item->addOption($option);
}
While I understand that it doesn't answer my question directly, I think there's just no method of loading options inside quote item.
So maybe someone will find the above piece of code useful.
Let's me share what I can do for my case to get cart item option, here is my piece of code:
foreach ($item->getOptions() as $option) {
if ($option->getCode() == 'info_buyRequest') {
$values = unserialize($option->getValue()); // to array object
// lookup custom option
if ($values && array_key_exists('options', $values)) {
//
}
}
}
As above code, I get all options of cart/quote item and lookup to find the code of info_buyRequest which stores the buying option of the item. My case, I was trying to look for the custom option of product that bought.
Note: You can check your item array data via: $item->getData() so that we can understand the structure of the data output.
In my case, I am adding additional options to the quote item in an observer. These options are not saved on the product in the backend as they are created dynamically.
In the cart, you can then simply use:
$quoteItem = someMethodToGetYourQuoteItem();
$quoteItem->getBuyRequest()->getYouroption();
Well right now you instantiate a new quote item object without any data. If you would load an actual quote item, you can use the function getOptions to retrieve all the options associated with the quote item.
What is it you want to do exactly?

How can I pull k2 items into my custom components view?

I am working on a custom joomla component and have a single view setup. I am trying to figure out how to pull a list of k2 items into the view based on a few custom filters...
In weird english it would something like this:
Get all k2 items that_match_some_requirements into my custom components view where user_id = this user
It would be nice to be able to reference the item data normally like so:
$this->item->info
I am really just trying to understand / figure out the best way to import k2 item's and their object into my components view. If that makes sense?
Maybe something with this? Although I feel the name indicates otherwise :-/
JModelLegacy::addIncludePath(JPATH_SITE . '/components/com_component/models');
$whateverModel = JModelLegacy::getInstance('something', 'something'); //? not sure
or maybe from this module code?
require_once (JPATH_SITE.DS.'components'.DS.'com_k2'.DS.'helpers'.DS.'route.php');
require_once (JPATH_SITE.DS.'components'.DS.'com_k2'.DS.'helpers'.DS.'utilities.php');
class modK2ContentHelper
{
public static function getItems(&$params, $format = 'html')
{
jimport('joomla.filesystem.file');
$mainframe = JFactory::getApplication();
$limit = $params->get('itemCount', 5);
$cid = $params->get('category_id', NULL);
$ordering = $params->get('itemsOrdering', '');
$componentParams = JComponentHelper::getParams('com_k2');
$limitstart = JRequest::getInt('limitstart');
Thank you!
I think it's easier your second option. Actually the whole process of getting K2 items with specific conditions is specified in the helper.php file.
In line 261:
$items = $db->loadObjectList();
The objects are loaded after the query has been created (the code is too long to be pasted here).
In the next lines you can see how a lot of item properties are created, modified or generated (300 lines of code).
At the end you get an array of items (php objects):
...
$rows[] = $item;
}
return $rows;
...
You could just take this file and reuse the code, or even call it from your component assuming always that the module is installed.

looping through product collection and saving products is changing attribute values unintended changes

I am running a loop through a product collection like the following
$productCollection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect('small_image')
->addAttributeToSelect('thumbnail')
->addAttributeToSelect('image')
->addAttributeToSelect('sku');
foreach($productCollection as $product){
$product->setSmallImage($product->getImage());
$product->setThumbnail($product->getImage());
$product->save();
}
I am setting the other image types to the same as the base image because the client forgot to set those in the import sheet. For some reason when doing this it is setting the visibility of all products to Catalog, Search. A lot of my products are suppose to be "Not Visible Individually", so of course this messes stuff up.
Any Idea why this value would change, and are there other values that might change based on how I looped through the product collection?
I think it is because i removed the addAttributeToSelect(*) and did it specific to the two attributes but when trying to do the product collection over 18k products it was crapping out
Ok so this is what I found. When saving an object in Magento, it will call the normal Model abstract save method, this then calls $this->_getResource()->save($this); which will call the entity abstract save method, which eventually gets to /app/code/core/Mage/Eav/Model/Entity/Abstract.php and its _beforeSave() method which calls the walkAttributes($partMethod, array $args=array()) method.
A long the way all the attributes are loaded the the Resource object of the entity. The walkAttributes method will go through all attributes associated to the entity and calls this method call_user_func_array(array($instance, $method), $args); and in my case it is calling the beforeSave method for an attribute, as you can see here
/app/code/core/Mage/Eav/Model/Entity/Attribute/Backend/Abstract.php
public function beforeSave($object)
{
$attrCode = $this->getAttribute()->getAttributeCode();
if (!$object->hasData($attrCode) && $this->getDefaultValue()) {
$object->setData($attrCode, $this->getDefaultValue());
}
}
So any attribute that does not have any data and has a default value, that default value is applied to the object, in sense overwriting my data that is really set just not loaded to my object. I am guessing the best way to loop over thousands of products is to set the pageSize to a number that your server can handle loading and then you can set addAttributeToSelect('*'). However I am not aware of the best way to loop over this correctly, so for me I might just load the product in the for loop and not set the attribute to select all.
Here is my attempt at looping over the whole collection, please post any improvements
$productCollection = Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect('*')->setPageSize(200);
for ($i = 1; $i <= $productCollection->getLastPageNumber(); $i++) {
if ($productCollection->isLoaded()) {
$productCollection->clear();
$productCollection->setPage($i);
$productCollection->setPageSize(200);
}
foreach ($productCollection as $product) {
echo $product->getId() . "\n\n";
}
echo $i . "\n\n";
}
I would like to still hear any other input on this as to whether this is the right thinking or explanation of the problem.
I actually found a better way to loop over a large collection, which is to use the resource iterator model and here is a tutorial on how to do so from the Fontis guys
http://www.fontis.com.au/blog/magento/loading-large-collections

Categories