Related
I am trying to override the Topmenu block in Magento 2 so that I can change the HTML structure of my sub menus but I can't seem to get past this problem.
What I have done
I have created a module called Ecommerce\Topmenu.
Files
app/code/Ecommerce/Topmenu
-- etc/
--- di.xml
--- module.xml
-- Plugin/
--- Topmenu.php
-- registration.php
Topmenu.php
<?php
/**
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Ecommerce\Topmenu\Plugin;
use \Magento\Framework\DataObject\IdentityInterface;
use \Magento\Framework\View\Element\Template;
use \Magento\Framework\Data\TreeFactory;
use \Magento\Framework\Data\Tree\Node;
use \Magento\Framework\Data\Tree\NodeFactory;
/**
* Html page top menu block
*/
class Topmenu extends \Magento\Theme\Block\Html\Topmenu
{
/**
* Get top menu html
*
* #param string $outermostClass
* #param string $childrenWrapClass
* #param int $limit
* #return string
*/
public function getHtml($outermostClass = '', $childrenWrapClass = '', $limit = 0)
{
$this->_eventManager->dispatch(
'page_block_html_topmenu_gethtml_before',
['menu' => $this->_menu, 'block' => $this]
);
$this->_menu->setOutermostClass($outermostClass);
$this->_menu->setChildrenWrapClass($childrenWrapClass);
$html = $this->_getHtml($this->_menu, $childrenWrapClass, $limit);
$transportObject = new \Magento\Framework\DataObject(['html' => $html]);
$this->_eventManager->dispatch(
'page_block_html_topmenu_gethtml_after',
['menu' => $this->_menu, 'transportObject' => $transportObject]
);
$html = $transportObject->getHtml();
return $html;
}
/**
* Count All Subnavigation Items
*
* #param \Magento\Backend\Model\Menu $items
* #return int
*/
protected function _countItems($items)
{
$total = $items->count();
foreach ($items as $item) {
/** #var $item \Magento\Backend\Model\Menu\Item */
if ($item->hasChildren()) {
$total += $this->_countItems($item->getChildren());
}
}
return $total;
}
/**
* Building Array with Column Brake Stops
*
* #param \Magento\Backend\Model\Menu $items
* #param int $limit
* #return array|void
*
* #todo: Add Depth Level limit, and better logic for columns
*/
protected function _columnBrake($items, $limit)
{
$total = $this->_countItems($items);
if ($total <= $limit) {
return;
}
$result[] = ['total' => $total, 'max' => (int)ceil($total / ceil($total / $limit))];
$count = 0;
$firstCol = true;
foreach ($items as $item) {
$place = $this->_countItems($item->getChildren()) + 1;
$count += $place;
if ($place >= $limit) {
$colbrake = !$firstCol;
$count = 0;
} elseif ($count >= $limit) {
$colbrake = !$firstCol;
$count = $place;
} else {
$colbrake = false;
}
$result[] = ['place' => $place, 'colbrake' => $colbrake];
$firstCol = false;
}
return $result;
}
/**
* Add sub menu HTML code for current menu item
*
* #param \Magento\Framework\Data\Tree\Node $child
* #param string $childLevel
* #param string $childrenWrapClass
* #param int $limit
* #return string HTML code
*/
protected function _addSubMenu($child, $childLevel, $childrenWrapClass, $limit)
{
$html = '';
if (!$child->hasChildren()) {
return $html;
}
$colStops = null;
if ($childLevel == 0 && $limit) {
$colStops = $this->_columnBrake($child->getChildren(), $limit);
}
$html .= '<ul class="level' . $childLevel . ' megaSub">';
$html .= $this->_getHtml($child, $childrenWrapClass, $limit, $colStops);
$html .= '</ul>';
return $html;
}
/**
* Recursively generates top menu html from data that is specified in $menuTree
*
* #param \Magento\Framework\Data\Tree\Node $menuTree
* #param string $childrenWrapClass
* #param int $limit
* #param array $colBrakes
* #return string
*
* #SuppressWarnings(PHPMD.CyclomaticComplexity)
* #SuppressWarnings(PHPMD.NPathComplexity)
*/
protected function _getHtml(
\Magento\Framework\Data\Tree\Node $menuTree,
$childrenWrapClass,
$limit,
$colBrakes = []
) {
$html = '';
$children = $menuTree->getChildren();
$parentLevel = $menuTree->getLevel();
$childLevel = $parentLevel === null ? 0 : $parentLevel + 1;
$counter = 1;
$itemPosition = 1;
$childrenCount = $children->count();
$parentPositionClass = $menuTree->getPositionClass();
$itemPositionClassPrefix = $parentPositionClass ? $parentPositionClass . '-' : 'nav-';
foreach ($children as $child) {
$child->setLevel($childLevel);
$child->setIsFirst($counter == 1);
$child->setIsLast($counter == $childrenCount);
$child->setPositionClass($itemPositionClassPrefix . $counter);
$outermostClassCode = '';
$outermostClass = $menuTree->getOutermostClass();
if ($childLevel == 0 && $outermostClass) {
$outermostClassCode = ' class="' . $outermostClass . '" ';
$child->setClass($outermostClass);
}
if (count($colBrakes) && $colBrakes[$counter]['colbrake']) {
// $html .= '</ul></li><li class="column"><ul>';
}
if($counter > 1 && $childLevel == 1){
continue;
}
$html .= '<li ' . $this->_getRenderedMenuItemAttributes($child) . '>';
$html .= '<a href="' . $child->getUrl() . '" ' . $outermostClassCode . '><span>' . $this->escapeHtml(
$child->getName()
) . '</span></a>' . $this->_addSubMenu(
$child,
$childLevel,
$childrenWrapClass,
$limit
) . '</li>';
$itemPosition++;
$counter++;
}
if (count($colBrakes) && $limit) {
$html = '<li class="column"><ul>' . $html . '</ul></li>';
}
return $html;
}
/**
* Generates string with all attributes that should be present in menu item element
*
* #param \Magento\Framework\Data\Tree\Node $item
* #return string
*/
protected function _getRenderedMenuItemAttributes(\Magento\Framework\Data\Tree\Node $item)
{
$html = '';
$attributes = $this->_getMenuItemAttributes($item);
foreach ($attributes as $attributeName => $attributeValue) {
$html .= ' ' . $attributeName . '="' . str_replace('"', '\"', $attributeValue) . '"';
}
return $html;
}
/**
* Returns array of menu item's attributes
*
* #param \Magento\Framework\Data\Tree\Node $item
* #return array
*/
protected function _getMenuItemAttributes(\Magento\Framework\Data\Tree\Node $item)
{
$menuItemClasses = $this->_getMenuItemClasses($item);
return ['class' => implode(' ', $menuItemClasses)];
}
/**
* Returns array of menu item's classes
*
* #param \Magento\Framework\Data\Tree\Node $item
* #return array
*/
protected function _getMenuItemClasses(\Magento\Framework\Data\Tree\Node $item)
{
$classes = [];
$classes[] = 'level' . $item->getLevel();
$classes[] = $item->getPositionClass();
if ($item->getIsFirst()) {
$classes[] = 'first';
}
if ($item->getIsActive()) {
$classes[] = 'active';
} elseif ($item->getHasActive()) {
$classes[] = 'has-active';
}
if ($item->getIsLast()) {
$classes[] = 'last';
}
if ($item->getClass()) {
$classes[] = $item->getClass();
}
if ($item->hasChildren()) {
$classes[] = 'parent';
}
return $classes;
}
/**
* Add identity
*
* #param array $identity
* #return void
*/
public function addIdentity($identity)
{
if (!in_array($identity, $this->identities)) {
$this->identities[] = $identity;
}
}
/**
* Get identities
*
* #return array
*/
public function getIdentities()
{
return $this->identities;
}
/**
* Get cache key informative items
*
* #return array
*/
public function getCacheKeyInfo()
{
$keyInfo = parent::getCacheKeyInfo();
$keyInfo[] = $this->getUrl('*/*/*', ['_current' => true, '_query' => '']);
return $keyInfo;
}
/**
* Get tags array for saving cache
*
* #return array
*/
protected function getCacheTags()
{
return array_merge(parent::getCacheTags(), $this->getIdentities());
}
/**
* Get menu object.
*
* #return Node
*/
public function getMenu()
{
return $this->_menu;
}
}
** Expected behavour **
My module should override the Magento Topmenu module whilst inheriting it allowing me to change the output markup
The problem
After running setup:upgrade and recompiling, I am just presented with the following error:
Fatal error: Call to a member function setOutermostClass() on null in /var/www/myecom.co.uk/app/code/Ecommerce/Topmenu/Plugin/Topmenu.php on line 36
It's like my code is not correctly extending the Topmenu block.
Any ideas?
For fix this my solution is insert construct as below:
public function __construct(Template\Context $context, NodeFactory $nodeFactory, TreeFactory $treeFactory, array $data = [])
{
parent::__construct($context, $nodeFactory, $treeFactory, $data);
$this->nodeFactory = $nodeFactory;
$this->treeFactory = $treeFactory;
}
This problem is a result of a recent Magento update which explains why I was having this problem using code that had previously worked for me on earlier Magento versions.
Final Solution
The final solution to fix this after Magento's update is to replace $this->_menu with $this->getMenu()
Now the working version of my custom module extends the Magento top menu class and just overrides the _getHtml function to change the markup as required.
I am using codeigniter 2.0 version. In datatables query not working using datatable method. But when i run this in mysql means it is perfectly working. I dont know how to solve this issue. Below i have given my query,
$this->load->library('datatables');
$this->datatables->query("select sales.id as id, sales.date as date, sales.customer_name, sale_items.product_name as pname, sales.depositcard_amt as debit, 0 as credit from sales join sale_items on sale_items.sale_id=sales.id where sales.customer_id = $user and sales.branch_id=$branchid and sales.depositcard_amt != 0.00 group by sales.id UNION ALL select deposit.id as id, deposit.credit_on as date, deposit_details.customer_name, deposit_details.package_name as pname, 0 as debit, deposit.total_amount as credit from deposit join deposit_details on deposit_details.deposit_id=deposit.id where deposit.customers=$user");
$this->datatables->add_column("Actions",
"<center></center>", "id")
->unset_column('id');
echo $this->datatables->generate();
Please give any ideas to solve this. Thanks in advance.
Library Datatables.php
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Ignited Datatables
*
* This is a wrapper class/library based on the native Datatables server-side implementation by Allan Jardine
* found at http://datatables.net/examples/data_sources/server_side.html for CodeIgniter
*
* #package CodeIgniter
* #subpackage libraries
* #category library
* #version 1.15
* #author Vincent Bambico <metal.conspiracy#gmail.com>
* Yusuf Ozdemir <yusuf#ozdemir.be>
* #link http://ellislab.com/forums/viewthread/160896/
*/
class Datatables
{
/**
* Global container variables for chained argument results
*
*/
private $ci;
private $table;
private $distinct;
private $query ;
private $fadu = "" ;
private $group_by = array();
private $order_by = array();
private $select = array();
private $joins = array();
private $left_joins = array();
private $outer_joins = array();
private $columns = array();
private $where = array();
private $or_where = array();
private $like = array();
private $filter = array();
private $add_columns = array();
private $edit_columns = array();
private $unset_columns = array();
/**
* Copies an instance of CI
*/
public function __construct()
{
$this->ci =& get_instance();
}
/**
* If you establish multiple databases in config/database.php this will allow you to
* set the database (other than $active_group) - more info: http://ellislab.com/forums/viewthread/145901/#712942
*/
public function set_database($db_name)
{
$db_data = $this->ci->load->database($db_name, TRUE);
$this->ci->db = $db_data;
}
/**
* Generates the SELECT portion of the query
*
* #param string $columns
* #param bool $backtick_protect
* #return mixed
*/
public function select($columns, $backtick_protect = TRUE)
{
foreach ($this->explode(',', $columns) as $val) {
$column = trim(preg_replace('/(.*)\s+as\s+(\w*)/i', '$2', $val));
$this->columns[] = $column;
$this->select[$column] = trim(preg_replace('/(.*)\s+as\s+(\w*)/i', '$1', $val));
}
$this->ci->db->select($columns, $backtick_protect);
return $this;
}
/**
* Generates the DISTINCT portion of the query
*
* #param string $column
* #return mixed
*/
public function distinct($column)
{
$this->distinct = $column;
$this->ci->db->distinct($column);
return $this;
}
/**
* Generates a custom GROUP BY portion of the query
*
* #param string $val
* #return mixed
*/
public function group_by($val)
{
$this->group_by[] = $val;
$this->ci->db->group_by($val);
return $this;
}
public function order_by($val, $direction = '')
{
$this->order_by[] = array($val, $direction );
$this->ci->db->order_by($val, $direction );
return $this;
}
public function query($val)
{
$this->query = $val;
$this->table = "";
return $this;
}
/**
* Generates the FROM portion of the query
*
* #param string $table
* #return mixed
*/
public function from($table , $fadu = "")
{
$this->table = $table;
$this->fadu = $fadu;
return $this;
}
/**
* Generates the JOIN portion of the query
*
* #param string $table
* #param string $fk
* #param string $type
* #return mixed
*/
public function join($table, $fk, $type = NULL)
{
$this->joins[] = array($table, $fk, $type);
$this->ci->db->join($table, $fk, $type);
return $this;
}
public function left_join($table, $fk, $type = NULL)
{
$this->left_joins[] = array($table, $fk, $type);
$this->ci->db->left_join($table, $fk, $type);
return $this;
}
public function outer_join($table, $fk, $type = NULL)
{
$this->outer_joins[] = array($table, $fk, $type);
$this->ci->db->outer_join($table, $fk, $type);
return $this;
}
/**
* Generates the WHERE portion of the query
*
* #param mixed $key_condition
* #param string $val
* #param bool $backtick_protect
* #return mixed
*/
public function where($key_condition, $val = NULL, $backtick_protect = TRUE)
{
$this->where[] = array($key_condition, $val, $backtick_protect);
$this->ci->db->where($key_condition, $val, $backtick_protect);
return $this;
}
/**
* Generates the WHERE portion of the query
*
* #param mixed $key_condition
* #param string $val
* #param bool $backtick_protect
* #return mixed
*/
public function or_where($key_condition, $val = NULL, $backtick_protect = TRUE)
{
$this->or_where[] = array($key_condition, $val, $backtick_protect);
$this->ci->db->or_where($key_condition, $val, $backtick_protect);
return $this;
}
/**
* Generates the WHERE portion of the query
*
* #param mixed $key_condition
* #param string $val
* #param bool $backtick_protect
* #return mixed
*/
public function filter($key_condition, $val = NULL, $backtick_protect = TRUE)
{
$this->filter[] = array($key_condition, $val, $backtick_protect);
return $this;
}
/**
* Generates a %LIKE% portion of the query
*
* #param mixed $key_condition
* #param string $val
* #param bool $backtick_protect
* #return mixed
*/
public function like($key_condition, $val = NULL, $backtick_protect = TRUE)
{
$this->like[] = array($key_condition, $val, $backtick_protect);
$this->ci->db->like($key_condition, $val, $backtick_protect);
return $this;
}
/**
* Sets additional column variables for adding custom columns
*
* #param string $column
* #param string $content
* #param string $match_replacement
* #return mixed
*/
public function add_column($column, $content, $match_replacement = NULL)
{
$this->add_columns[$column] = array('content' => $content, 'replacement' => $this->explode(',', $match_replacement));
return $this;
}
/**
* Sets additional column variables for editing columns
*
* #param string $column
* #param string $content
* #param string $match_replacement
* #return mixed
*/
public function edit_column($column, $content, $match_replacement)
{
$this->edit_columns[$column][] = array('content' => $content, 'replacement' => $this->explode(',', $match_replacement));
return $this;
}
/**
* Unset column
*
* #param string $column
* #return mixed
*/
public function unset_column($column)
{
$column = explode(',', $column);
$this->unset_columns = array_merge($this->unset_columns, $column);
return $this;
}
/**
* Builds all the necessary query segments and performs the main query based on results set from chained statements
*
* #param string $output
* #param string $charset
* #return string
*/
public function generate($output = 'json', $charset = 'UTF-8')
{
if (strtolower($output) == 'json')
$this->get_paging();
$this->get_ordering();
$this->get_filtering();
return $this->produce_output(strtolower($output), strtolower($charset));
}
/**
* Generates the LIMIT portion of the query
*
* #return mixed
*/
private function get_paging()
{
$iStart = $this->ci->input->post('iDisplayStart');
$iLength = $this->ci->input->post('iDisplayLength');
if ($iLength != '' && $iLength != '-1')
$this->ci->db->limit($iLength, ($iStart) ? $iStart : 0);
}
/**
* Generates the ORDER BY portion of the query
*
* #return mixed
*/
private function get_ordering()
{
if ($this->check_mDataprop())
$mColArray = $this->get_mDataprop();
elseif ($this->ci->input->post('sColumns'))
$mColArray = explode(',', $this->ci->input->post('sColumns'));
else
$mColArray = $this->columns;
$mColArray = array_values(array_diff($mColArray, $this->unset_columns));
$columns = array_values(array_diff($this->columns, $this->unset_columns));
for ($i = 0; $i < intval($this->ci->input->post('iSortingCols')); $i++)
if (isset($mColArray[intval($this->ci->input->post('iSortCol_' . $i))]) && in_array($mColArray[intval($this->ci->input->post('iSortCol_' . $i))], $columns) && $this->ci->input->post('bSortable_' . intval($this->ci->input->post('iSortCol_' . $i))) == 'true')
$this->ci->db->order_by($mColArray[intval($this->ci->input->post('iSortCol_' . $i))], $this->ci->input->post('sSortDir_' . $i));
}
/**
* Generates a %LIKE% portion of the query
*
* #return mixed
*/
private function get_filtering()
{
if ($this->check_mDataprop())
$mColArray = $this->get_mDataprop();
elseif ($this->ci->input->post('sColumns'))
$mColArray = explode(',', $this->ci->input->post('sColumns'));
else
$mColArray = $this->columns;
$sWhere = '';
$sSearch = $this->ci->db->escape_like_str($this->ci->input->post('sSearch'));
$mColArray = array_values(array_diff($mColArray, $this->unset_columns));
$columns = array_values(array_diff($this->columns, $this->unset_columns));
if ($sSearch != '')
for ($i = 0; $i < count($mColArray); $i++)
if ($this->ci->input->post('bSearchable_' . $i) == 'true' && in_array($mColArray[$i], $columns))
$sWhere .= $this->select[$mColArray[$i]] . " LIKE '%" . $sSearch . "%' OR ";
$sWhere = substr_replace($sWhere, '', -3);
if ($sWhere != '')
$this->ci->db->where('(' . $sWhere . ')');
$sRangeSeparator = $this->ci->input->post('sRangeSeparator');
for ($i = 0; $i < intval($this->ci->input->post('iColumns')); $i++) {
if (isset($_POST['sSearch_' . $i]) && $this->ci->input->post('sSearch_' . $i) != '' && in_array($mColArray[$i], $columns)) {
$miSearch = explode(',', $this->ci->input->post('sSearch_' . $i));
foreach ($miSearch as $val) {
if (preg_match("/(<=|>=|=|<|>)(\s*)(.+)/i", trim($val), $matches))
$this->ci->db->where($this->select[$mColArray[$i]] . ' ' . $matches[1], $matches[3]);
elseif (!empty($sRangeSeparator) && preg_match("/(.*)$sRangeSeparator(.*)/i", trim($val), $matches)) {
$rangeQuery = '';
if (!empty($matches[1]))
$rangeQuery = 'STR_TO_DATE(' . $this->select[$mColArray[$i]] . ",'%d/%m/%y %H:%i:%s') >= STR_TO_DATE('" . $matches[1] . " 00:00:00','%d/%m/%y %H:%i:%s')";
if (!empty($matches[2]))
$rangeQuery .= (!empty($rangeQuery) ? ' AND ' : '') . 'STR_TO_DATE(' . $this->select[$mColArray[$i]] . ",'%d/%m/%y %H:%i:%s') <= STR_TO_DATE('" . $matches[2] . " 23:59:59','%d/%m/%y %H:%i:%s')";
if (!empty($matches[1]) || !empty($matches[2]))
$this->ci->db->where($rangeQuery);
} else
$this->ci->db->where($this->select[$mColArray[$i]] . ' LIKE', '%' . $val . '%');
}
}
}
foreach ($this->filter as $val)
$this->ci->db->where($val[0], $val[1], $val[2]);
}
/**
* Compiles the select statement based on the other functions called and runs the query
*
* #return mixed
*/
private function get_display_result()
{
if($this->fadu != "")
{
return $this->ci->db->query($this->table);
}
else
{
return $this->ci->db->get($this->table);
}
}
/**
* Builds an encoded string data. Returns JSON by default, and an array of aaData and sColumns if output is set to raw.
*
* #param string $output
* #param string $charset
* #return mixed
*/
private function produce_output($output, $charset)
{
$aaData = array();
$rResult = $this->get_display_result();
if ($output == 'json') {
$iTotal = $this->get_total_results();
$iFilteredTotal = $this->get_total_results(TRUE);
}
foreach ($rResult->result_array() as $row_key => $row_val) {
$aaData[$row_key] = ($this->check_mDataprop()) ? $row_val : array_values($row_val);
foreach ($this->add_columns as $field => $val)
if ($this->check_mDataprop())
$aaData[$row_key][$field] = $this->exec_replace($val, $aaData[$row_key]);
else
$aaData[$row_key][] = $this->exec_replace($val, $aaData[$row_key]);
foreach ($this->edit_columns as $modkey => $modval)
foreach ($modval as $val)
$aaData[$row_key][($this->check_mDataprop()) ? $modkey : array_search($modkey, $this->columns)] = $this->exec_replace($val, $aaData[$row_key]);
$aaData[$row_key] = array_diff_key($aaData[$row_key], ($this->check_mDataprop()) ? $this->unset_columns : array_intersect($this->columns, $this->unset_columns));
if (!$this->check_mDataprop())
$aaData[$row_key] = array_values($aaData[$row_key]);
}
$sColumns = array_diff($this->columns, $this->unset_columns);
$sColumns = array_merge_recursive($sColumns, array_keys($this->add_columns));
if ($output == 'json') {
$sOutput = array
(
'sEcho' => intval($this->ci->input->post('sEcho')),
'iTotalRecords' => $iTotal,
'iTotalDisplayRecords' => $iFilteredTotal,
'aaData' => $aaData,
'sColumns' => implode(',', $sColumns)
);
if ($charset == 'utf-8')
return json_encode($sOutput);
else
return $this->jsonify($sOutput);
} else
return array('aaData' => $aaData, 'sColumns' => $sColumns);
}
/**
* Get result count
*
* #return integer
*/
private function get_total_results($filtering = FALSE)
{
if ($filtering)
$this->get_filtering();
foreach ($this->joins as $val)
$this->ci->db->join($val[0], $val[1], $val[2]);
foreach ($this->where as $val)
$this->ci->db->where($val[0], $val[1], $val[2]);
foreach ($this->or_where as $val)
$this->ci->db->or_where($val[0], $val[1], $val[2]);
foreach ($this->group_by as $val)
$this->ci->db->group_by($val);
foreach ($this->like as $val)
$this->ci->db->like($val[0], $val[1], $val[2]);
if (strlen($this->distinct) > 0) {
$this->ci->db->distinct($this->distinct);
$this->ci->db->select($this->columns);
}
if($this->fadu != "")
{
$query = $this->ci->db->query($this->table);
}
else
{
$query = $this->ci->db->get($this->table, NULL, NULL, FALSE);
}
return $query->num_rows();
}
/**
* Runs callback functions and makes replacements
*
* #param mixed $custom_val
* #param mixed $row_data
* #return string $custom_val['content']
*/
private function exec_replace($custom_val, $row_data)
{
$replace_string = '';
if (isset($custom_val['replacement']) && is_array($custom_val['replacement'])) {
foreach ($custom_val['replacement'] as $key => $val) {
$sval = preg_replace("/(?<!\w)([\'\"])(.*)\\1(?!\w)/i", '$2', trim($val));
if (preg_match('/(\w+::\w+|\w+)\((.*)\)/i', $val, $matches) && is_callable($matches[1])) {
$func = $matches[1];
$args = preg_split("/[\s,]*\\\"([^\\\"]+)\\\"[\s,]*|" . "[\s,]*'([^']+)'[\s,]*|" . "[,]+/", $matches[2], 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
foreach ($args as $args_key => $args_val) {
$args_val = preg_replace("/(?<!\w)([\'\"])(.*)\\1(?!\w)/i", '$2', trim($args_val));
$args[$args_key] = (in_array($args_val, $this->columns)) ? ($row_data[($this->check_mDataprop()) ? $args_val : array_search($args_val, $this->columns)]) : $args_val;
}
$replace_string = call_user_func_array($func, $args);
} elseif (in_array($sval, $this->columns))
$replace_string = $row_data[($this->check_mDataprop()) ? $sval : array_search($sval, $this->columns)];
else
$replace_string = $sval;
$custom_val['content'] = str_ireplace('$' . ($key + 1), $replace_string, $custom_val['content']);
}
}
return $custom_val['content'];
}
/**
* Check mDataprop
*
* #return bool
*/
private function check_mDataprop()
{
if (!$this->ci->input->post('mDataProp_0'))
return FALSE;
for ($i = 0; $i < intval($this->ci->input->post('iColumns')); $i++)
if (!is_numeric($this->ci->input->post('mDataProp_' . $i)))
return TRUE;
return FALSE;
}
/**
* Get mDataprop order
*
* #return mixed
*/
private function get_mDataprop()
{
$mDataProp = array();
for ($i = 0; $i < intval($this->ci->input->post('iColumns')); $i++)
$mDataProp[] = $this->ci->input->post('mDataProp_' . $i);
return $mDataProp;
}
/**
* Return the difference of open and close characters
*
* #param string $str
* #param string $open
* #param string $close
* #return string $retval
*/
private function balanceChars($str, $open, $close)
{
$openCount = substr_count($str, $open);
$closeCount = substr_count($str, $close);
$retval = $openCount - $closeCount;
return $retval;
}
/**
* Explode, but ignore delimiter until closing characters are found
*
* #param string $delimiter
* #param string $str
* #param string $open
* #param string $close
* #return mixed $retval
*/
private function explode($delimiter, $str, $open = '(', $close = ')')
{
$retval = array();
$hold = array();
$balance = 0;
$parts = explode($delimiter, $str);
foreach ($parts as $part) {
$hold[] = $part;
$balance += $this->balanceChars($part, $open, $close);
if ($balance < 1) {
$retval[] = implode($delimiter, $hold);
$hold = array();
$balance = 0;
}
}
if (count($hold) > 0)
$retval[] = implode($delimiter, $hold);
return $retval;
}
/**
* Workaround for json_encode's UTF-8 encoding if a different charset needs to be used
*
* #param mixed $result
* #return string
*/
private function jsonify($result = FALSE)
{
if (is_null($result))
return 'null';
if ($result === FALSE)
return 'false';
if ($result === TRUE)
return 'true';
if (is_scalar($result)) {
if (is_float($result))
return floatval(str_replace(',', '.', strval($result)));
if (is_string($result)) {
static $jsonReplaces = array(array('\\', '/', '\n', '\t', '\r', '\b', '\f', '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'));
return '"' . str_replace($jsonReplaces[0], $jsonReplaces[1], $result) . '"';
} else
return $result;
}
$isList = TRUE;
for ($i = 0, reset($result); $i < count($result); $i++, next($result)) {
if (key($result) !== $i) {
$isList = FALSE;
break;
}
}
$json = array();
if ($isList) {
foreach ($result as $value)
$json[] = $this->jsonify($value);
return '[' . join(',', $json) . ']';
} else {
foreach ($result as $key => $value)
$json[] = $this->jsonify($key) . ':' . $this->jsonify($value);
return '{' . join(',', $json) . '}';
}
}
}
/* End of file Datatables.php */
/* Location: ./application/libraries/Datatables.php */
Now
Your query something like
$this->load->library('datatables');
$this->datatables->from("select sales.id as id, sales.date as date,
sales.customer_name, sale_items.product_name as pname, sales.depositcard_amt as debit,
0 as credit from sales join sale_items on sale_items.sale_id=sales.id
where sales.customer_id = $user
and sales.branch_id=$branchid
and sales.depositcard_amt != 0.00
group by sales.id
UNION ALL
select deposit.id as id, deposit.credit_on as date,
deposit_details.customer_name, deposit_details.package_name as pname,
0 as debit, deposit.total_amount as credit from deposit
join deposit_details on deposit_details.deposit_id=deposit.id where deposit.customers=$user" ,"a");
$this->datatables->add_column("Actions", "<center></center>", "id");
$this->datatables->unset_column('id');
echo $this->datatables->generate();
I have found a php inventory http://inventory-management.org/ easy but was written in PHP4? and I run now on PHP5. I have found some errors that I have already managed to fix but they are keep coming up so I would like to see if I can managed to run at the end. (As it is really simple script only has 5-7 php files).
Could someone help me please how to fix this error?
Fatal error: Cannot redeclare fputcsv() in C:\xampp\htdocs\Inventory\lib\common.php on line 935
which is:
function fputcsv ($fp, $array, $deliminator=",") {
return fputs($fp, putcsv($array,$delimitator));
}#end fputcsv()
here is the full code:
<?php
/*
*/
/**
* description returns an array with filename base name and the extension
*
* #param filemane format
*
* #return array
*
* #access public
*/
function FileExt($filename) {
//checking if the file have an extension
if (!strstr($filename, "."))
return array("0"=>$filename,"1"=>"");
//peoceed to normal detection
$filename = strrev($filename);
$extpos = strpos($filename , ".");
$file = strrev(substr($filename , $extpos + 1));
$ext = strrev(substr($filename , 0 , $extpos));
return array("0"=>$file,"1"=>$ext);
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function UploadFile($source, $destination , $name ="") {
$name = $name ? $name : basename($source);
$name = FileExt($name);
$name[2]= $name[0];
$counter = 0 ;
while (file_exists( $destination . $name[0] . "." . $name[1] )) {
$name[0] = $name[2] . $counter;
$counter ++;
}
copy($source , $destination . $name[0] . "." . $name[1] );
#chmod($destination . $name[0] . "." . $name[1] , 0777);
}
function UploadFileFromWeb($source, $destination , $name) {
$name = FileExt($name);
$name[2]= $name[0];
$counter = 0 ;
while (file_exists( $destination . $name[0] . "." . $name[1] )) {
$name[0] = $name[2] . $counter;
$counter ++;
}
SaveFileContents($destination . $name[0] . "." . $name[1] , $source);
#chmod($destination . $name[0] . "." . $name[1] , 0777);
}
/**
* returns the contents of a file in a string
*
* #param string $file_name name of file to be loaded
*
* #return string
*
* #acces public
*/
function GetFileContents($file_name) {
// if (!file_exists($file_name)) {
// return null;
// }
//echo "<br>:" . $file_name;
$file = fopen($file_name,"r");
//checking if the file was succesfuly opened
if (!$file)
return null;
if (strstr($file_name,"://"))
while (!feof($file))
$result .= fread($file,1024);
else
$result = #fread($file,filesize($file_name));
fclose($file);
return $result;
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function SaveFileContents($file_name,$content) {
// echo $file_name;
$file = fopen($file_name,"w");
fwrite($file,$content);
fclose($file);
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function Debug($what,$pre = 1,$die = 0) {
if (PB_DEBUG_EXT == 1) {
if ($pre == 1)
echo "<pre style=\"background-color:white;\">";
print_r($what);
if ($pre == 1)
echo "</pre>";
if ($die == 1)
die;
}
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function SendMail($to,$from,$subject,$message,$to_name,$from_name) {
if ($to_name)
$to = "$to_name <$to>";
$headers = "MIME-Version: 1.0\n";
$headers .= "Content-type: text; charset=iso-8859-1\n";
if ($from_name) {
$headers .= "From: $from_name <$from>\n";
$headers .= "Reply-To: $from_name <$from>\n";
}
else {
$headers .= "From: $from\n";
$headers .= "Reply-To: $from\n";
}
$headers .= "X-Mailer: PHP/" . phpversion();
return mail($to, $subject, $message,$headers);
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function FillVars($var,$fields,$with) {
$fields = explode (",",$fields);
foreach ($fields as $field)
if (!$var[$field])
!$var[$field] = $with;
return $var;
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function CleanupString($string,$strip_tags = TRUE) {
$string = addslashes(trim($string));
if ($strip_tags)
$string = strip_tags($string);
return $string;
}
define("RX_EMAIL","^[a-z0-9]+([_\\.-][a-z0-9]+)*#([a-z0-9]+([\.-][a-z0-9]+)*)+\\.[a-z]{2,}$");
define("RX_CHARS","[a-z\ ]");
define("RX_DIGITS","[0-9]");
define("RX_ALPHA","[^a-z0-9_]");
define("RX_ZIP","[0-9\-]");
define("RX_PHONE","[0-9\-\+\(\)]");
/**
* description
*
* #param
*
* #return
*
* #access
*/
function CheckString($string,$min,$max,$regexp = "",$rx_result = FALSE) {
if (get_magic_quotes_gpc() == 0)
$string = CleanupString($string);
if (strlen($string) < $min)
return 1;
elseif (($max != 0) && (strlen($string) > $max))
return 2;
elseif ($regexp != "")
if ($rx_result == eregi($regexp,$string))
return 3;
return 0;
}
/**
* description
*
* #param
*
* #return
*
* #access
*/// FIRST_NAME:S:3:60,LAST_NAME:S...
function ValidateVars($source,$vars) {
$vars = explode(",",$vars);
foreach ($vars as $var) {
list($name,$type,$min,$max) = explode(":",$var);
switch ($type) {
case "S":
$type = RX_CHARS;
$rx_result = FALSE;
break;
case "I":
$type = RX_DIGITS;
$rx_result = TRUE;
break;
case "E":
$type = RX_EMAIL;
$rx_result = FALSE;
break;
case "P":
$type = RX_PHONE;
$rx_result = TRUE;
break;
case "Z":
$type = RX_ZIP;
$rx_result = FALSE;
break;
case "A":
$type = "";
break;
case "F":
//experimental crap
$type = RX_ALPHA;
$rx_result = TRUE;
//$source[strtolower($name)] = str_replace(" ", "" , $source[strtolower($name)] );
break;
}
//var_dump($result);
if (($result = CheckString($source[strtolower($name)],$min,$max,$type,$rx_result)) != 0)
$errors[] = $name;
}
return is_array($errors) ? $errors : 0;
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function ResizeImage($source,$destination,$size) {
if (PB_IMAGE_MAGICK == 1)
system( PB_IMAGE_MAGICK_PATH . "convert $source -resize {$size}x{$size} $destination");
else
copy($source,$destination);
}
/**
* uses microtime() to return the current unix time w/ microseconds
*
* #return float the current unix time in the form of seconds.microseconds
*
* #access public
*/
function GetMicroTime() {
list($usec,$sec) = explode(" ",microtime());
return (float) $usec + (float) $sec;
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function GetArrayPart($input,$from,$count) {
$return = array();
$max = count($input);
for ($i = $from; $i < $from + $count; $i++ )
if ($i<$max)
$return[] = $input[$i];
return $return;
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function ReplaceAllImagesPath($htmldata,$image_path) {
$htmldata = stripslashes($htmldata);
// replacing IE formating style
$htmldata = str_replace("<IMG","<img",$htmldata);
// esmth, i dont know why i'm doing
preg_match_all("'<img.*?>'si",$htmldata,$images);
//<?//ing edit plus
foreach ($images[0] as $image)
$htmldata = str_replace($image,ReplaceImagePath($image,$image_path),$htmldata);
return $htmldata;//implode("\n",$html_out);
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function ReplaceImagePath($image,$replace) {
// removing tags
$image = stripslashes($image);
$image = str_replace("<","",$image);
$image = str_replace(">","",$image);
// exploging image in proprietes
$image_arr = explode(" ",$image);
for ($i = 0;$i < count($image_arr) ;$i++ ) {
if (stristr($image_arr[$i],"src")) {
// lets it :]
$image_arr[$i] = explode("=",$image_arr[$i]);
// modifing the image path
// i doing this
// replacing ',"
$image_arr[$i][1] = str_replace("'","",$image_arr[$i][1]);
$image_arr[$i][1] = str_replace("\"","",$image_arr[$i][1]);
//getting only image name
$image_arr[$i][1] = strrev(substr(strrev($image_arr[$i][1]),0,strpos(strrev($image_arr[$i][1]),"/")));
// building the image back
$image_arr[$i][1] = "\"" . $replace . $image_arr[$i][1] . "\"";
$image_arr[$i] = implode ("=",$image_arr[$i]);
}
}
// adding tags
return "<" . implode(" ",$image_arr) . ">";
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function DowloadAllImages($images,$path) {
foreach ($images as $image)
#SaveFileContents($path ."/".ExtractFileNameFromPath($image),#implode("",#file($image)));
}
function GetAllImagesPath($htmldata) {
$htmldata = stripslashes($htmldata);
// replacing IE formating style
$htmldata = str_replace("<IMG","<img",$htmldata);
// esmth, i dont know why i'm doing
preg_match_all("'<img.*?>'si",$htmldata,$images);
//<?//ing edit plus
foreach ($images[0] as $image)
$images_path[] = GetImageName($image);
return $images_path;
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function GetImagePath($image) {
// removing tags
$image = stripslashes($image);
$image = str_replace("<","",$image);
$image = str_replace(">","",$image);
// exploging image in proprietes
$image_arr = explode(" ",$image);
for ($i = 0;$i < count($image_arr) ;$i++ ) {
if (stristr($image_arr[$i],"src")) {
// lets it :]
$image_arr[$i] = explode("=",$image_arr[$i]);
// modifing the image path
// i doing this
// replacing ',"
$image_arr[$i][1] = str_replace("'","",$image_arr[$i][1]);
$image_arr[$i][1] = str_replace("\"","",$image_arr[$i][1]);
return strrev(substr(strrev($image_arr[$i][1]),0,strpos(strrev($image_arr[$i][1]),"/")));;
}
}
// adding tags
return "";
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function GetImageName($image) {
// removing tags
$image = stripslashes($image);
$image = str_replace("<","",$image);
$image = str_replace(">","",$image);
// exploging image in proprietes
$image_arr = explode(" ",$image);
for ($i = 0;$i < count($image_arr) ;$i++ ) {
if (stristr($image_arr[$i],"src")) {
// lets it :]
$image_arr[$i] = explode("=",$image_arr[$i]);
// modifing the image path
// i doing this
// replacing ',"
$image_arr[$i][1] = str_replace("'","",$image_arr[$i][1]);
$image_arr[$i][1] = str_replace("\"","",$image_arr[$i][1]);
return $image_arr[$i][1];
}
}
// adding tags
return "";
}
/**
* reinventing the wheel [badly]
*
* #param somthin
*
* #return erroneous
*
* #access denied
*/
function ExtractFileNameFromPath($file) {
//return strrev(substr(strrev($file),0,strpos(strrev($file),"/")));
// sau ai putea face asha. umpic mai smart ca mai sus dar tot stupid
// daca le dai path fara slashes i.e. un filename prima returneaza "" asta taie primu char
//return substr($file,strrpos($file,"/") + 1,strlen($file) - strrpos($file,"/"));
// corect ar fi cred asha [observa smart usage`u de strRpos]
//return substr($file,strrpos($file,"/") + (strstr($file,"/") ? 1 : 0),strlen($file) - strrpos($file,"/"));
// sau putem folosi tactica `nute mai caca pe tine and rtm' shi facem asha
return basename($file);
// har har :]]
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function RemoveArraySlashes($array) {
if ($array)
foreach ($array as $key => $item)
if (is_array($item))
$array[$key] = RemoveArraySlashes($item);
else
$array[$key] = stripslashes($item);
return $array;
}
function AddArraySlashes($array) {
if ($array)
foreach ($array as $key => $item)
if (is_array($item))
$array[$key] = AddArraySlashes($item);
else
$array[$key] = addslashes($item);
return $array;
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function Ahtmlentities($array) {
if (is_array($array))
foreach ($array as $key => $item)
if (is_array($item))
$array[$key] = ahtmlentities($item);
else
$array[$key] = htmlentities(stripslashes($item),ENT_COMPAT);
else
return htmlentities(stripslashes($array),ENT_COMPAT);
return $array;
}
function AStripSlasshes($array) {
if (is_array($array))
foreach ($array as $key => $item)
if (is_array($item))
$array[$key] = AStripSlasshes($item);
else
$array[$key] = stripslashes($item);
else
return stripslashes($array);
return $array;
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function Ahtml_entity_decode($array) {
if ($array)
foreach ($array as $key => $item)
if (is_array($item))
$array[$key] = ahtml_entity_decode($item);
else
$array[$key] = html_entity_decode($item,ENT_COMPAT);
return $array;
}
function array2xml ($name, $value, $indent = 1)
{
$indentstring = "\t";
for ($i = 0; $i < $indent; $i++)
{
$indentstring .= $indentstring;
}
if (!is_array($value))
{
$xml = $indentstring.'<'.$name.'>'.$value.'</'.$name.'>'."\n";
}
else
{
if($indent === 1)
{
$isindex = False;
}
else
{
$isindex = True;
while (list ($idxkey, $idxval) = each ($value))
{
if ($idxkey !== (int)$idxkey)
{
$isindex = False;
}
}
}
reset($value);
while (list ($key, $val) = each ($value))
{
if($indent === 1)
{
$keyname = $name;
$nextkey = $key;
}
elseif($isindex)
{
$keyname = $name;
$nextkey = $name;
}
else
{
$keyname = $key;
$nextkey = $key;
}
if (is_array($val))
{
$xml .= $indentstring.'<'.$keyname.'>'."\n";
$xml .= array2xml ($nextkey, $val, $indent+1);
$xml .= $indentstring.'</'.$keyname.'>'."\n";
}
else
{
$xml .= array2xml ($nextkey, $val, $indent);
}
}
}
return $xml;
}
function GetPhpContent($file) {
if (file_exists($file) ) {
$data = GetFileContents($file);
//replacing special chars in content
$data = str_replace("<?php","",$data);
$data = str_replace("?>","",$data);
return $data;
}
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function KeyArray($array,$recurse = 0 , $count = 1) {
if (is_array($array)) {
foreach ($array as $key => $val) {
$array[$key]["key"] = $count ++;
if ($recurse) {
foreach ($array[$key] as $k => $val)
if (is_array($val)) {
KeyArray($array[$key][$k] , $recurse , $count);
}
}
}
}
return $count + 1;
}
function RandomWord( $passwordLength ) {
$password = "";
for ($index = 1; $index <= $passwordLength; $index++) {
// Pick random number between 1 and 62
$randomNumber = rand(1, 62);
// Select random character based on mapping.
if ($randomNumber < 11)
$password .= Chr($randomNumber + 48 - 1); // [ 1,10] => [0,9]
else if ($randomNumber < 37)
$password .= Chr($randomNumber + 65 - 10); // [11,36] => [A,Z]
else
$password .= Chr($randomNumber + 97 - 36); // [37,62] => [a,z]
}
return $password;
}
function DeleteFolder($file) {
if (file_exists($file)) {
chmod($file,0777);
if (is_dir($file)) {
$handle = opendir($file);
while($filename = readdir($handle)) {
if ($filename != "." && $filename != "..") {
DeleteFolder($file."/".$filename);
}
}
closedir($handle);
rmdir($file);
} else {
unlink($file);
}
}
}
function GenerateRecordID($array) {
$max = 0;
if (is_array($array)) {
foreach ($array as $key => $val)
$max = ($key > $max ? $key : $max);
return $max + 1;
}
else return 1;
}
/*****************************************************
Links cripting for admin
DO NOT TOUCH UNLKESS YOU KNOW WHAT YOU ARE DOING
*****************************************************/
/**
* description
*
* #param
*
* #return
*
* #access
*/
function CryptLink($link) {
if (defined("PB_CRYPT_LINKS") && (PB_CRYPT_LINKS == 1)) {
if (stristr($link,"javascript:")) {
/* if (stristr($link,"window.location=")) {
$pos = strpos($link , "window.location=");
$js = substr($link , 0 , $pos + 17 );
$final = substr($link , $pos + 17 );
$final = substr($final, 0, strlen($final) - 1 );
//well done ... crypt the link now
$url = #explode("?" , $final);
if (!is_array($url))
$url[0] = $final;
$tmp = str_replace( $url[0] . "?" , "" , $final);
$uri = urlencode(urlencode(base64_encode(str_rot13($tmp))));
$link = $js . $url[0] . "?" . $uri . md5($uri) . "'";
}
*/
} else {
$url = #explode("?" , $link);
if (!is_array($url))
$url[0] = $link;
$tmp = str_replace( $url[0] . "?" , "" , $link);
$uri = urlencode(urlencode(base64_encode(str_rot13($tmp))));
$link = $url[0] . "?" . $uri . md5($uri);
}
}
return $link;
}
/************************************************************************/
/* SOME PREINITIALISATION CRAP*/
if (defined("PB_CRYPT_LINKS") && (PB_CRYPT_LINKS == 1) ) {
$key = key($_GET);
if (is_array($_GET) && (count($_GET) == 1) && ($_GET[$key] == "")) {
$tmp = $_SERVER["QUERY_STRING"];
//do the md5 check
$md5 = substr($tmp , -32);
$tmp = substr($tmp , 0 , strlen($tmp) - 32);
if ($md5 != md5($tmp)) {
//header("index.php?action=badrequest");
//exit;
die("Please dont change the links!");
}
$tmp = str_rot13(base64_decode(urldecode(urldecode($tmp))));
$tmp_array = #explode("&" , $tmp);
$tmp_array = is_array($tmp_array) ? $tmp_array : array($tmp);
if (is_array($tmp_array)) {
foreach ($tmp_array as $key => $val) {
$tmp2 = explode("=" , $val);
$out[$tmp2[0]] = $tmp2[1];
}
} else {
$tmp2 = explode("=" , $tmp);
$out[$tmp2[0]] = $tmp2[1];
}
$_GET = $out;
}
}
/***********************************************************************/
function ArrayReplace($what , $with , $array ) {
if ($array)
foreach ($array as $key => $item)
if (is_array($item))
$array[$key] = ArrayReplace($what , $with , $item);
else
$array[$key] = str_replace($what , $with , $item);
return $array;
}
function stri_replace( $find, $replace, $string )
{
$parts = explode( strtolower($find), strtolower($string) );
$pos = 0;
foreach( $parts as $key=>$part ){
$parts[ $key ] = substr($string, $pos, strlen($part));
$pos += strlen($part) + strlen($find);
}
return( join( $replace, $parts ) );
}
/**
* description
*
* #param
*
* #return
*
* #access
*/
function GMTDate($format , $date) {
global $_GMT;
return date($format , $date - $_GMT);
}
function putcsv ($array, $deliminator=",") {
$line = "";
foreach($array as $val) {
# remove any windows new lines,
# as they interfere with the parsing at the other end
$val = str_replace("\r\n", "\n", $val);
# if a deliminator char, a double quote char or a newline
# are in the field, add quotes
if(ereg("[$deliminator\"\n\r]", $val)) {
$val = '"'.str_replace('"', '""', $val).'"';
}#end if
$line .= $val.$deliminator;
}#end foreach
# strip the last deliminator
$line = substr($line, 0, (strlen($deliminator) * -1));
# add the newline
$line .= "\n";
# we don't care if the file pointer is invalid,
# let fputs take care of it
return $line;
}#end fputcsv()
function fputcsv ($fp, $array, $deliminator=",") {
return fputs($fp, putcsv($array,$delimitator));
}#end fputcsv()
/**
* description
*
* #param
*
* #return
*
* #access
*/
function is_subaction($sub,$action) {
return (bool)($_GET["sub"] == $sub) && ($_GET["action"] == $action);
}
?>
many thanks in advance
fputcsv() is a built in PHP function. This means you cannot name your own function the same thing.
If you need this code to work with PHP4, just check to see if the function exists first, then if not, create your own.
if (!function_exists('fputcsv')) {
// Your definition here
}
I am getting this PHP fatal error message: "Fatal error: Class PT_Fieldtype contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (EE_Fieldtype::display_field) in /.../pt_fieldtype.php on line 148"
However, when I open the file and do a search, the word "abstract" is nowhere to be found at all. Thanks for the help!
Edit: Here's the code in question. My bad for not showing it before.
<?php if (! defined('BASEPATH')) exit('No direct script access allowed');
if (! defined('PT_FIELD_PACK_VER'))
{
// get the version from config.php
require PATH_THIRD.'pt_field_pack/config.php';
define('PT_FIELD_PACK_VER', $config['version']);
}
/**
* P&T Fieldtype Base Class
*
* #package P&T Field Pack
* #author Brandon Kelly <brandon#pixelandtonic.com>
* #copyright Copyright (c) 2010 Pixel & Tonic, LLC
*/
class PT_Fieldtype extends EE_Fieldtype {
/**
* PT_Fieldtype Constructor
*/
function PT_Fieldtype()
{
parent::EE_Fieldtype();
}
// --------------------------------------------------------------------
/**
* Options Setting
*/
function options_setting($options=array(), $indent = '')
{
$r = '';
foreach($options as $name => $label)
{
if ($r !== '') $r .= "\n";
// is this just a blank option?
if (! $name && ! $label) $name = $label = ' ';
$r .= $indent . htmlentities($name);
// is this an optgroup?
if (is_array($label)) $r .= "\n".$this->options_setting($label, $indent.' ');
else if ($name != $label) $r .= ' : '.$label;
}
return $r;
}
// --------------------------------------------------------------------
/**
* Save Options Setting
*/
function save_options_setting($options = '', $total_levels = 1)
{
// prepare options
$options = preg_split('/[\r\n]+/', $options);
foreach($options as &$option)
{
$option_parts = preg_split('/\s:\s/', $option, 2);
$option = array();
$option['indent'] = preg_match('/^\s+/', $option_parts[0], $matches) ? strlen(str_replace("\t", ' ', $matches[0])) : 0;
$option['name'] = trim($option_parts[0]);
$option['value'] = isset($option_parts[1]) ? trim($option_parts[1]) : $option['name'];
}
return $this->_structure_options($options, $total_levels);
}
/**
* Structure Options
*/
private function _structure_options(&$options, $total_levels, $level = 1, $indent = -1)
{
$r = array();
while ($options)
{
if ($indent == -1 || $options[0]['indent'] > $indent)
{
$option = array_shift($options);
$children = (! $total_levels OR $level < $total_levels)
? $this->_structure_options($options, $total_levels, $level+1, $option['indent']+1)
: FALSE;
$r[(string)$option['name']] = $children ? $children : (string)$option['value'];
}
else if ($options[0]['indent'] <= $indent)
{
break;
}
}
return $r;
}
// --------------------------------------------------------------------
/**
* Prep Iterators
*/
function prep_iterators(&$tagdata)
{
// find {switch} tags
$this->_switches = array();
$tagdata = preg_replace_callback('/'.LD.'switch\s*=\s*([\'\"])([^\1]+)\1'.RD.'/sU', array(&$this, '_get_switch_options'), $tagdata);
$this->_count_tag = 'count';
$this->_iterator_count = 0;
}
/**
* Get Switch Options
*/
function _get_switch_options($match)
{
global $FNS;
$marker = LD.'SWITCH['.$FNS->random('alpha', 8).']SWITCH'.RD;
$this->_switches[] = array('marker' => $marker, 'options' => explode('|', $match[2]));
return $marker;
}
/**
* Parse Iterators
*/
function parse_iterators(&$tagdata)
{
// {switch} tags
foreach($this->_switches as $i => $switch)
{
$option = $this->_iterator_count % count($switch['options']);
$tagdata = str_replace($switch['marker'], $switch['options'][$option], $tagdata);
}
// update the count
$this->_iterator_count++;
// {count} tags
$tagdata = $this->EE->TMPL->swap_var_single($this->_count_tag, $this->_iterator_count, $tagdata);
}
}
// ====================================================================
/**
* P&T Multi Fieldtype Base Class
*
* #package P&T Field Pack
* #author Brandon Kelly <brandon#pixelandtonic.com>
* #copyright Copyright (c) 2010 Pixel & Tonic, LLC
*/
class PT_Multi_Fieldtype extends PT_Fieldtype {
var $default_field_settings = array(
'options' => array(
'Option 1' => 'Option 1',
'Option 2' => 'Option 2',
'Option 3' => 'Option 3'
)
);
var $default_cell_settings = array(
'options' => array(
'Opt 1' => 'Opt 1',
'Opt 2' => 'Opt 2'
)
);
var $default_tag_params = array(
'sort' => '',
'backspace' => '0'
);
var $total_option_levels = 1;
// --------------------------------------------------------------------
/**
* Display Field Settings
*/
function display_settings($data)
{
// load the language file
$this->EE->lang->loadfile($this->class);
$options = isset($data['options']) ? $data['options'] : array();
$input_name = $this->class.'_options';
$this->EE->table->add_row(
lang($this->class.'_options', $input_name) . '<br />'
. lang('field_list_instructions') . '<br /><br />'
. lang('option_setting_examples'),
'<textarea id="'.$input_name.'" name="'.$input_name.'" rows="6">'.$this->options_setting($options).'</textarea>'
);
}
/**
* Display Cell Settings
*/
function display_cell_settings($data)
{
// load the language file
$this->EE->lang->loadfile($this->class);
$options = isset($data['options']) ? $data['options'] : array();
return array(
array(
lang($this->class.'_options'),
'<textarea class="matrix-textarea" name="options" rows="4">'.$this->options_setting($options).'</textarea>'
)
);
}
// --------------------------------------------------------------------
/**
* Save Field Settings
*/
function save_settings($data)
{
$post = $this->EE->input->post($this->class.'_options');
// replace quotes
$post = str_replace('"', '"', $post);
return array(
'options' => $this->save_options_setting($post, $this->total_option_levels)
);
}
/**
* Save Cell Settings
*/
function save_cell_settings($settings)
{
// replace quotes
$settings['options'] = str_replace('"', '"', $settings['options']);
$settings['options'] = $this->save_options_setting($settings['options'], $this->total_option_levels);
return $settings;
}
// --------------------------------------------------------------------
/**
* Prep Field Data
*
* Ensures $field_data is an array.
*/
function prep_field_data(&$data)
{
if (! is_array($data))
{
$data = array_filter(preg_split("/[\r\n]+/", $data));
}
}
// --------------------------------------------------------------------
/**
* Display Field
*/
function display_field($data)
{
if (is_string($data)) $data = html_entity_decode($data);
return $this->_display_field($data, $this->field_name);
}
/**
* Display Cell
*/
function display_cell($data)
{
return $this->_display_field($data, $this->cell_name);
}
// --------------------------------------------------------------------
/**
* Save
*/
function save($data)
{
// replace quotes
return str_replace('"', '"', $data);
}
/**
* Save Cell
*/
function save_cell($data)
{
// replace quotes
return $this->save($data);
}
// --------------------------------------------------------------------
/**
* Find Options
*/
private function _find_option($needle, $haystack)
{
foreach ($haystack as $key => $value)
{
$r = $value;
if ($needle == $key OR (is_array($value) AND (($r = $this->_find_option($needle, $value)) !== FALSE)))
{
return $r;
}
}
return FALSE;
}
// --------------------------------------------------------------------
/**
* Replace Tag
*/
function replace_tag($data, $params = array(), $tagdata = FALSE)
{
if (! isset($this->settings['options']) || ! $this->settings['options'])
{
return $data;
}
if (! $tagdata)
{
return $this->replace_ul($data, $params);
}
$this->prep_field_data($data);
$r = '';
if ($this->settings['options'] && $data)
{
// optional sorting
if (isset($params['sort']) && $params['sort'])
{
$sort = strtolower($params['sort']);
if ($sort == 'asc')
{
sort($data);
}
else if ($sort == 'desc')
{
rsort($data);
}
}
// offset and limit
if (isset($params['offset']) || isset($params['limit']))
{
$offset = isset($params['offset']) ? $params['offset'] : 0;
$limit = isset($params['limit']) ? $params['limit'] : count($data);
$data = array_splice($data, $offset, $limit);
}
// prepare for {switch} and {count} tags
$this->prep_iterators($tagdata);
foreach($data as $option_name)
{
if (($option = $this->_find_option($option_name, $this->settings['options'])) !== FALSE)
{
// copy $tagdata
$option_tagdata = $tagdata;
// simple var swaps
$option_tagdata = $this->EE->TMPL->swap_var_single('option', $option, $option_tagdata);
$option_tagdata = $this->EE->TMPL->swap_var_single('option_name', $option_name, $option_tagdata);
// parse {switch} and {count} tags
$this->parse_iterators($option_tagdata);
$r .= $option_tagdata;
}
}
if (isset($params['backspace']) && $params['backspace'])
{
$r = substr($r, 0, -$params['backspace']);
}
}
return $r;
}
// --------------------------------------------------------------------
/**
* Unordered List
*/
function replace_ul($data, $params = array())
{
return "<ul>\n"
. $this->replace_tag($data, $params, " <li>{option}</li>\n")
. '</ul>';
}
/**
* Ordered List
*/
function replace_ol($data, $params = array())
{
return "<ol>\n"
. $this->replace_tag($data, $params, " <li>{option}</li>\n")
. '</ol>';
}
// --------------------------------------------------------------------
/**
* All Options
*/
function replace_all_options($data, $params = array(), $tagdata = FALSE, $options = FALSE, $iterator_count = 0)
{
if (! $tagdata)
{
return "<ul>\n"
. $this->replace_all_options($data, $params, " <li>{option}</li>\n")
. "</ul>";
}
PT_Multi_Fieldtype::prep_field_data($data);
$r = '';
if ($options === FALSE)
{
$options = $this->settings['options'];
}
if ($options)
{
// optional sorting
if (isset($params['sort']) && $params['sort'])
{
$sort = strtolower($params['sort']);
if ($sort == 'asc')
{
asort($options);
}
else if ($sort == 'desc')
{
arsort($options);
}
}
// prepare for {switch} and {count} tags
$this->prep_iterators($tagdata);
$this->_iterator_count += $iterator_count;
foreach($options as $option_name => $option)
{
if (is_array($option))
{
$sub_params = array_merge($params, array('backspace' => '0'));
$r .= $this->replace_all_options($data, $sub_params, $tagdata, $option, $this->_iterator_count);
}
else
{
// copy $tagdata
$option_tagdata = $tagdata;
// simple var swaps
$option_tagdata = $this->EE->TMPL->swap_var_single('option', $option, $option_tagdata);
$option_tagdata = $this->EE->TMPL->swap_var_single('option_name', $option_name, $option_tagdata);
$option_tagdata = $this->EE->TMPL->swap_var_single('selected', (in_array($option_name, $data) ? 1 : 0), $option_tagdata);
// parse {switch} and {count} tags
$this->parse_iterators($option_tagdata);
$r .= $option_tagdata;
}
}
if (isset($params['backspace']) && $params['backspace'])
{
$r = substr($r, 0, -$params['backspace']);
}
}
return $r;
}
// --------------------------------------------------------------------
/**
* Is Selected?
*/
function replace_selected($data, $params = array())
{
$this->prep_field_data($data);
return (isset($params['option']) AND in_array($params['option'], $data)) ? 1 : 0;
}
/**
* Total Selections
*/
function replace_total_selections($data, $params = array())
{
$this->prep_field_data($data);
return $field_data ? (string) count($data) : '0';
}
}
The answer of your question is on line 148 of this file...
Maybe you are using a class with abstract methods without inheriting them that is rejected, make sure you implement all of them and after show us some code. ;-)
I'm trying to implement code for nested commenting which I found at http://www.jongales.com/blog/2009/01/27/php-class-for-threaded-comments/.
But for some reason I can't get it to work. My result is
"Parent Child Child Third level Second Parent Second Child" in one row
without any nesting. What am I doing wrong? Is there maybe a setting or extension which I have to enable for this to work? Thanks in advance!
Here's the exact code I'm using:
<?php
class Threaded_comments
{
public $parents = array();
public $children = array();
/**
* #param array $comments
*/
function __construct($comments)
{
foreach ($comments as $comment)
{
if ($comment['parent_id'] === NULL)
{
$this->parents[$comment['id']][] = $comment;
}
else
{
$this->children[$comment['parent_id']][] = $comment;
}
}
}
/**
* #param array $comment
* #param int $depth
*/
private function format_comment($comment, $depth)
{
for ($depth; $depth > 0; $depth--)
{
echo "\t";
}
echo $comment['text'];
echo "\n";
}
/**
* #param array $comment
* #param int $depth
*/
private function print_parent($comment, $depth = 0)
{
foreach ($comment as $c)
{
$this->format_comment($c, $depth);
if (isset($this->children[$c['id']]))
{
$this->print_parent($this->children[$c['id']], $depth + 1);
}
}
}
public function print_comments()
{
foreach ($this->parents as $c)
{
$this->print_parent($c);
}
}
}
$comments = array( array('id'=>1, 'parent_id'=>NULL, 'text'=>'Parent'),
array('id'=>2, 'parent_id'=>1, 'text'=>'Child'),
array('id'=>3, 'parent_id'=>2, 'text'=>'Child Third level'),
array('id'=>4, 'parent_id'=>NULL, 'text'=>'Second Parent'),
array('id'=>5, 'parent_id'=>4, 'text'=>'Second Child')
);
$threaded_comments = new Threaded_comments($comments);
$threaded_comments->print_comments();
?>
I think you will only see the formating in a console, not if use it in a web page. if you want it in a web page you must replace the \n and \t in the following function with <br/> and respectively.
/**
* #param array $comment
* #param int $depth
*/
private function format_comment($comment, $depth)
{
for ($depth; $depth > 0; $depth--)
{
echo "\t";
}
echo $comment['text'];
echo "\n";
}
should become :
/**
* #param array $comment
* #param int $depth
*/
private function format_comment($comment, $depth)
{
for ($depth; $depth > 0; $depth--)
{
echo " ";
}
echo $comment['text'];
echo "<br />";
}