Category tree in a laravel routing - laravel

I am doing a product catalogue with Eloquent and i have 2 models: product and category. Each category can have many products and each product belongs to one category. My category model has the following columns:
id
title
parent_id
slug
and product model has:
id
title
body
category_id
slug
When i am creating a category, by default parent_id set to 0, which means it's not a subcategory, but parent, i.e.:
Cars
--Audi
Cars has parent_id set to 0 and Audi has parent_id set to 1 (because Cars category's id is 1). Then i created model for nested rows:
ItemsHelper.php:
<?php
class ItemsHelper {
private $items;
public function __construct($items) {
$this->items = $items;
}
public function htmlList() {
return $this->htmlFromArray($this->itemArray());
}
private function itemArray() {
$result = array();
foreach($this->items as $item) {
if ($item->parent_id == 0) {
$result[$item->title] = $this->itemWithChildren($item);
}
}
return $result;
}
private function childrenOf($item) {
$result = array();
foreach($this->items as $i) {
if ($i->parent_id == $item->id) {
$result[] = $i;
}
}
return $result;
}
private function itemWithChildren($item) {
$result = array();
$children = $this->childrenOf($item);
foreach ($children as $child) {
$result[$child->title] = $this->itemWithChildren($child);
}
return $result;
}
private function htmlFromArray($array) {
$html = '';
foreach($array as $k => $v) {
$html .= "<ul>";
$html .= "<li>" . $k . "</li>";
if(count($v) > 0) {
$html .= $this->htmlFromArray($v);
}
$html .= "</ul>";
}
return $html;
}
}
then i am printing category hierarchy in a blade file:
{{ $itemsHelper->htmlList() }}
it outputs a category tree. I can access cars category by visiting /category/cars but if it's children of cars category then it should be /category/cars/audi How can i set that in my routes?
routes.php:
Route::resource('category', 'CategoryController');

Related

Laravel method in getCustomAttribute returning cullection null

I am trying to modify $category->slug by getSlugAttribute(). My Category class like this,
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
class Category extends Model
{
public function getSlugAttribute(){
return $this->getRoute($this);
}
//Testing _____________________________________________________
private $routes = [];
public function getRoute(Category $category)
{
$this->determineCategoriesRoutes();
return $this->routes[$category->id];
}
private function determineCategoriesRoutes()
{
$categories = $this->all()->keyBy('id');
foreach ($categories as $id => $category) {
$slugs = $this->determineCategorySlugs($category, $categories);
if (count($slugs) === 1) {
$this->routes[$id] = '/' . $slugs[0];
}
else {
$this->routes[$id] = '/' . implode('/', $slugs);
}
}
}
private function determineCategorySlugs(Category $category, Collection $categories, array $slugs = [])
{
array_unshift($slugs, $category->slug);
if ($category->parent_id != 0) {
$slugs = $this->determineCategorySlugs($categories[$category->parent_id], $categories, $slugs);
}
return $slugs;
}
//End Testing__________________________________________________
//end of this class
}
Now when I request for categories it's just loading and giving me a blank page.
Route::get('/test', function(App\Category $category){
$categories = $category->all();
return $categories;
});
This is my test route, also there is no error.

Best Practice: Models and Controllers

I would like to get your MVC experience on the following:
I have a table where I say which user_id is in which group_id and a second table where I say which user_id has which user_name.
Now I want a function to which I pass a group_id and it gives me all user_names in the group.
The question is, what does the Controller do and what the Model:
Controller calls a Model (get_user_ids_from_group) that returns the user ids and then the controler calls different model (get_user_name_by_id) to return the usernames.
A controller calls a Model (`get_user_names_from_group) and the model internally gets first the user ids and then the user names.
I understand that the first way is more MVC strict. But how strict would you be in a case like this? Right now I am always being very strict.
As a result my model functions have always just two lines (query and return) and my controller are bigger. So to make controller and model size more equal the second option would be possible.
Actually, it has nothing to do with MVC, as CodeIgniter doesn't implement MVC, but a sort of MVP.
However, if you're using RDBMS such as MySQL, you could JOIN these two table (within the Model) and fetch the result (within the Controller) as I suggested in a similar topic on SO.
application/models/user.php
class User extends CI_Model
{
public function get_users_by_group($group_id)
{
$this->db->select('*')->from('groups');
// While group_id and user_id have a N:1 relation
$this->db->where('group_id', $group_id);
$this->db->join('users', 'users.user_id = groups.user_id');
$query=$this->db->get();
return $query->result_array();
}
}
Then fetch and pass the result within the Controller:
application/controllers/users.php
class Users extends CI_Controller
{
public function view($group_id)
{
$this->load->model('user');
// Fetch the result from the database
$data['users'] = $this->user->get_users_by_group($group_id);
// Pass the result to the view
$this->load->view('users_view', $data);
}
}
In MVC model should not be only use for storing and getting the data but also it should contain the business logic.
Controller - Should take input communicate with model and view
Model - Should contain business logic and data store
View - Only for Output
So its like Input -> Process -> Output
Also its depend on you where to put what and you should have a balance code on controller and model, Not write everything in controller or in model
In you case I think you should uses get_user_names_from_group and just pass the group name and make a join query between two table. And when you define your function in the model its give you the option to reuse the function again in case you need same thing on next controller.
Common model example:
<?php
class Common_model extends CI_Model {
function get_entry_by_data($table_name, $single = false, $data = array(), $select = "", $order_by = '', $orderby_field = '', $limit = '', $offset = 0, $group_by = '') {
if (!empty($select)) {
$this->db->select($select);
}
if (empty($data)) {
$id = $this->input->post('id');
if (!$id)
return false;
$data = array('id' => $id);
}
if (!empty($group_by)) {
$this->db->group_by($group_by);
}
if (!empty($limit)) {
$this->db->limit($limit, $offset);
}
if (!empty($order_by) && !empty($orderby_field)) {
$this->db->order_by($orderby_field, $order_by);
}
$query = $this->db->get_where($table_name, $data);
$res = $query->result_array();
//echo $this->db->last_query();exit;
if (!empty($res)) {
if ($single)
return $res[0];
else
return $res;
} else
return false;
}
public function get_entry_by_data_in($table_name, $single = false, $data = array(), $select = "", $order_by = '', $orderby_field = '', $limit = '', $offset = 0, $group_by = '',$in_column='',$in_data=''){
if (!empty($select)) {
$this->db->select($select);
}
if (empty($data)) {
$id = $this->input->post('id');
if (!$id)
return false;
$data = array('id' => $id);
}
if (!empty($group_by)) {
$this->db->group_by($group_by);
}
if (!empty($limit)) {
$this->db->limit($limit, $offset);
}
if (!empty($order_by) && !empty($orderby_field)) {
$this->db->order_by($orderby_field, $order_by);
}
if (!empty($in_data) and !empty($in_column)) {
$this->db->where_in($in_column,$in_data);
}
$query = $this->db->get_where($table_name, $data);
$res = $query->result_array();
//echo $this->db->last_query();exit;
if (!empty($res)) {
if ($single)
return $res[0];
else
return $res;
} else
return false;
}
public function getAllRecords($table, $orderby_field = '', $orderby_val = '', $where_field = '', $where_val = '', $select = '', $limit = '', $limit_val = '') {
if (!empty($limit)) {
$offset = (empty($limit_val)) ? '0' : $limit_val;
$this->db->limit($limit, $offset);
}
if (!empty($select)) {
$this->db->select($select);
}
if ($orderby_field)
$this->db->order_by($orderby_field, $orderby_val);
if ($where_field)
$this->db->where($where_field, $where_val);
$query = $this->db->get($table);
//return $query->num_rows;
//echo $this->db->last_query();
if ($query->num_rows > 0) {
return $query->result_array();
}
}
function alldata($table) {
$query = $this->db->get($table);
return $query->result_array();
}
function alldata_count($table, $where) {
$query = $this->db->get_where($table, $where);
return $query->num_rows();
}
function insert_entry($table, $data) {
$this->db->insert($table, $data);
return $this->db->insert_id();
}
function update_entry($table_name, $data, $where) {
return $this->db->update($table_name, $data, $where);
}
public function get_data_by_join($table, $table2, $where, $table1_column, $table2_column, $limit = '', $order_column = '', $order_by = 'DESC', $select_columns = '', $is_single_record = false, $group_by = '', $join_by = '', $offset = '') {
if (!empty($select_columns)) {
$this->db->select($select_columns);
} else {
$this->db->select('*');
}
$this->db->from($table);
$this->db->join($table2, $table . '.' . $table1_column . '=' . $table2 . '.' . $table2_column, $join_by);
$this->db->where($where);
if (!empty($limit)) {
if (!empty($offset)) {
$this->db->limit($limit, $offset);
} else {
$this->db->limit($limit);
}
}
if (!empty($order_column)) {
$this->db->order_by($order_column, $order_by);
}
if (!empty($group_by)) {
$this->db->group_by($group_by);
}
$query = $this->db->get();
if ($query->num_rows() > 0) {
if ($is_single_record) {
$rs = $query->result_array();
return $rs[0];
} else {
return $query->result_array();
}
} else {
return false;
}
}
function DeleteRecord($table_name, $where) {
return $this->db->delete($table_name, $where);
}
function managerecord() {
$count = 1;
$where = array('channel_id' => 8,
'field_id_12 !=' => '');
$this->db->where($where);
$query = $this->db->get('channel_data');
$data = $query->result_array();
foreach ($data as $value) {
$id = $value['field_id_12'];
$update = array('telephone' => $value['field_id_53'],
'about' => $value['field_id_54'],
'license' => $value['field_id_18'],
'broker' => $value['field_id_19'],
'preferred' => 'yes');
$this->db->update('members', $update, array('member_id' => $id));
}
echo "done1";
}
public function get_content_landing_page($table = false, $field = false, $id = false, $id_name = false) {
$this->db->select($field);
$this->db->from($table);
$this->db->where($id_name, $id);
$query = $this->db->get();
return $query->result_array();
}
public function get_field_landing_page($id = false,$fields=false) {
$this->db->select($fields);
$this->db->from('terratino_form_fields_master');
$this->db->where('id', $id);
$query = $this->db->get();
return $query->result_array();
}
}
?>

How to create cron for partial invoice of an order

I want to create partial invoice for downloadable product of an order based on release date of that product, I have got so many solutions to create partial invoice but it's create the invoice for all product, not for selected one.
Here is the solution but don't forget to change condition according your requirement.
<?php
require_once '../app/Mage.php';
Mage::app('admin');
CapturePayment::createInvoice();
class CapturePayment {
public static function createInvoice() {
$orders = Mage::getModel('sales/order')->getCollection()
->addFieldToFilter('status', array('processing'));
foreach ($orders as $order) {
$orderId = $order->getIncrementId();
try {
if (!$order->getId() || !$order->canInvoice()) {
echo 'Invoice is not allowed for order=>.' . $orderId . "\n";
continue;
}
$items = $order->getAllItems();
$partial = false;
$qtys = array();
foreach ($items as $item) {
/* Check wheter we can create invoice for this item or not */
if (!CapturePayment::canInvoiceItem($item, array())) {
continue;
}
/* Get product id on the basis of order item id */
$productId = $item->getProductId();
/* If product is tablet then don't create invoice for the same */
/* Put your condition here for items you want to create the invoice e.g.*/
/* Load the product to get the release date */
$productDetails = Mage::getModel('catalog/product')->load($productId);
/* create your $qtys array here like */
$qtys['orderItemId'] = 'quantityOrdered';
/* NOTE: But if you don't want to craete invoice for any particular item then pass the '0' quantity for that item and set the value for $partial = true if some product remain in any order*/
}
/* Prepare the invoice to capture/create the invoice */
$invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice($qtys);
if (!$invoice->getTotalQty()) {
continue;
}
$amount = $invoice->getGrandTotal();
if ($partial) {
$amount = $invoice->getGrandTotal();
$invoice->register()->pay();
$invoice->getOrder()->setIsInProcess(true);
$history = $invoice->getOrder()->addStatusHistoryComment('Partial amount of $' . $amount . ' captured automatically.', false);
$history->setIsCustomerNotified(true);
$invoice->sendEmail(true, '');
$order->save();
Mage::getModel('core/resource_transaction')
->addObject($invoice)
->addObject($invoice->getOrder())
->save();
$invoice->save();
} else {
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE);
$invoice->register();
$invoice->getOrder()->setCustomerNoteNotify(true);
$invoice->getOrder()->setIsInProcess(false);
$invoice->getOrder()->setData('state', "complete");
$invoice->getOrder()->setStatus("complete");
$invoice->sendEmail(true, '');
$order->save();
Mage::getModel('core/resource_transaction')
->addObject($invoice)
->addObject($invoice->getOrder())
->save();
$invoice->save();
}
} catch (Exception $e) {
echo 'Exception in Order => ' . $orderId . '=>' . $e . "\n";
}
}
}
/* Check the invoice status for an item of an order */
public static function canInvoiceItem($item, $qtys=array()) {
if ($item->getLockedDoInvoice()) {
return false;
}
if ($item->isDummy()) {
if ($item->getHasChildren()) {
foreach ($item->getChildrenItems() as $child) {
if (empty($qtys)) {
if ($child->getQtyToInvoice() > 0) {
return true;
}
} else {
if (isset($qtys[$child->getId()]) && $qtys[$child->getId()] > 0) {
return true;
}
}
}
return false;
} else if ($item->getParentItem()) {
$parent = $item->getParentItem();
if (empty($qtys)) {
return $parent->getQtyToInvoice() > 0;
} else {
return isset($qtys[$parent->getId()]) && $qtys[$parent->getId()] > 0;
}
}
} else {
return $item->getQtyToInvoice() > 0;
}
}
}

Show admin labels of attribute options of configurable products

I want to show the attribute values of the configurable product on product listing page. I specifically need admin labels of the attribute options which are assigned to particular product.
In my case the attribute name is confi_color. So on list.phtml
if($_product->getTypeId()=='configurable'){
$colorList = array();
$attrs = $_product->getTypeInstance(true)->getConfigurableAttributesAsArray($_product);
foreach($attrs as $attr) {
if(0 == strcmp("config_color", $attr['attribute_code'])) {
$options = $attr['values'];
$arr = array();
$count = 0;
foreach($options as $option) {
//print_r($option);
$arr[$count] = $option['value_index'];
$count++;
}
$colorList = $_product->getAdminAttributeText($attr['attribute_id'],$arr);
//echo getAdminAttributeText($attributeCode);
}
}
echo '<div style="float:right;">';
if(count($colorList > 1)){
for($i=1;$i<count($colorList);$i++) {
echo '<div style="background:'.$colorList[$i].';float:left;display:block;width:16px;border:1px solid #B6B6B6;margin-right:2px;"> </div>';
//$optStr .= "<option value='".$valuesVal->getId()."'>".$valuesVal->getTitle()."</option>";
}
echo '</div><div style="clear:left;"></div>';
}
}
Now to get the admin labels in /app/code/core/Mage/Catalog/Model/Product.php to /app/code/local/Mage/Catalo
g/Model/Product.php crete a function:
public function getAdminAttributeText($attributeCode,$arr) {
$_attribute= $this->getResource()->getAttribute($attributeCode);
$_options= $_attribute->getSource()->getAllOptions(true, true);
$count = 0;
$flag = 0;
$returnArr = array();
foreach($_options as $option){
for($count=0;$count<=count($arr);$count++){
if ($option['value'] == $arr[$count]){
$returnArr[$flag] = $option['label'];
$flag++;
}
}
}
return($returnArr);
}

codeinighter where field = data from form

I'm trying to match up suppliers from a postcode search:
Model code:
function get_suppliers(){
$this->db->from('suppliers');
$this->db->where('postcode', $data);
$this->db->select('name,type,site,contact,number');
$q = $this->db->get();
if($q->num_rows() > 0) {
foreach($q->result() as $row) {
$data[] = $row;
}
return $data;
}
}
Controller code:
public function index()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('postcode','Postcode', 'required|numeric|exact_length[4]');
$data = array(
'postcode' => $this->input->post('postcode')
);
if($this->form_validation->run() == FALSE)
{
## reload page ##
$this->load->view('welcome_message');
}
else
{
$this->load->model('site_model');
$this->site_model->add_record($data);
echo("postcode entered");
$data['rows'] = $this->site_model->get_suppliers($data);
print_r($data);
}
}
Obviously ignore the printers and echo thats just me bring to see whats going on I'm pretty sure i need to just change the $data in model to something just not sure what(tried heaps of things)
Model:
function get_suppliers($postcode = '*') // <-- Capture the postcode
{
$this->db->from('suppliers');
$this->db->where('postcode', $postcode); // <-- pass it in here
$this->db->select('name,type,site,contact,number');
$q = $this->db->get();
if($q->num_rows() > 0)
{
foreach($q->result() as $row)
{
$data[] = $row;
}
return $data;
}
}
Controller:
public function index()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('postcode','Postcode', 'required|numeric|exact_length[4]');
$data = array(
'postcode' => $this->input->post('postcode')
);
if($this->form_validation->run() == FALSE)
{
## reload page ##
$this->load->view('welcome_message');
}
else
{
$this->load->model('site_model');
$this->site_model->add_record($data);
$data['rows'] = $this->site_model->get_suppliers( $data['postcode'] ); // <-- pass the postcode
echo("postcode entered: " . $data['postcode'] . "<pre>");
print_r($data);
}
}
In your model:
function get_suppliers($data = ''){
i.e.: You haven't included $data as the argument

Resources