How to count matching elements in a recursive XQuery function - xpath

The following code works, but now I want to specify as a parameter which occurrence of an element specified by the xpath will be affected (replaced, deleted, inserted, etc.)
declare function local:replace($doc as node(), $new-content as item()*,
$target-path as xs:string) {
local:transform($doc, $new-content, $target-path, 'replace', "")
};
declare function local:transform($node as node(), $new-content as item()*,
$target-path as xs:string, $action as xs:string, $path as xs:string)
as node()+ {
if ($node instance of element() and concat($path, "/", node-name($node)) = $target-path)
then
if ($action = 'insert-before')
then ($new-content, $node)
else
if ($action = 'insert-after')
then ($node, $new-content)
else
if ($action = 'insert-as-child')
then element {node-name($node)}
{
$node/#*
,
$new-content
,
for $child in $node/node()
return $child
}
else
if ($action = 'replace')
then $new-content
else
if ($action = 'delete')
then ()
else ()
else
if ($node instance of element())
then
element {node-name($node)}
{
$node/#*
,
for $child in $node/node()
return
local:transform($child, $new-content, $target-path, $action, concat($path, "/", node-name($node)))
}
else $node
};
let $doc :=
<fo:Test xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:books>
<!-- These are my books -->
<book title='xQuery for Dummys'>
<author>Jack Wizard</author>
<details>
<pages>221</pages>
</details>
</book>
<book title='Mysteries of xQuery'>
<author>Lost Linda</author>
<details>
<replace-this>Goodbye World!</replace-this>
<pages>40</pages>
</details>
</book>
</fo:books>
</fo:Test>
(: -------- My test -------- :)
let $new-content := <replaced>Hello World!</replaced> return
local:replace($doc, $new-content, '/fo:Test/fo:books/book/details/replace-this')
Obviously $global-counter = $global-counter + 1 isn't going to work. I want to pass in the occurrence I want as another parameter like this:
local:replace($doc, $new-content, '/fo:Test/fo:books/book/details/pages', 2)
And get this output:
<fo:Test xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:books>
<!-- These are my books -->
<book title='xQuery for Dummys'>
<author>Jack Wizard</author>
<details>
<pages>221</pages>
</details>
</book>
<book title='Mysteries of xQuery'>
<author>Lost Linda</author>
<details>
<replace-this>Goodbye World!</replace-this>
<replaced>Hello World!</replaced>
</details>
</book>
</fo:books>
</fo:Test>
Instead of this unwanted result I'd get with using local:replace($doc, $new-content, '/fo:Test/fo:books/book/details/pages')
<fo:Test xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:books>
<!-- These are my books -->
<book title='xQuery for Dummys'>
<author>Jack Wizard</author>
<details>
<replace-this>Goodbye World!</replace-this>
</details>
</book>
<book title='Mysteries of xQuery'>
<author>Lost Linda</author>
<details>
<replace-this>Goodbye World!</replace-this>
<replaced>Hello World!</replaced>
</details>
</book>
</fo:books>
</fo:Test>
Is there any way to keep count of the number of positive matches I get and add that to the condition? I'm stumped!

The following provides an example similar to what you are trying to achieve, it does so by using recursion and memorising the path as it goes so that it can compare against your path that you wish to replace.
This uses XQuery 3.1, however it could be rewritten in XQuery 1.0 by encoding/decoding the map structure to/from a sequence or an in-memory XML document.
xquery version "3.1";
declare namespace fo="http://www.w3.org/1999/XSL/Format";
declare %private function local:push-element($path-stack as map(xs:integer, map(xs:QName, xs:integer)), $element as element(), $depth as xs:integer) as map(xs:integer, map(xs:QName, xs:integer)) {
let $occurence-map := $path-stack($depth)
return
if(not(empty($occurence-map))) then
let $name-occurs := $occurence-map(node-name($element))
return
if($name-occurs) then
map:put($path-stack, $depth, map:put($occurence-map, node-name($element), $name-occurs + 1))
else
map:put($path-stack, $depth, map:put($occurence-map, node-name($element), 1))
else
map:put($path-stack, $depth, map { node-name($element) : 1 })
(: TODO to reduce memory you could remove (pop) any elements from the map which have depth gt $depth :)
};
declare %private function local:children($children as node()*, $replace as xs:string, $replacement as element(), $current-path as xs:QName*, $path-stack as map(xs:integer, map(xs:QName, xs:integer))) {
if($children)then
let $child := $children[1]
return
let $new-path-stack :=
if($child instance of element())then
local:push-element($path-stack, $child, count($current-path) + 1)
else
$path-stack
return
(
local:replace($child, $replace, $replacement, $current-path, $new-path-stack),
local:children(subsequence($children, 2), $replace, $replacement, $current-path, $new-path-stack)
)
else()
};
declare %private function local:get-occurence($name as xs:QName, $depth as xs:integer, $path-stack as map(xs:integer, map(xs:QName, xs:integer))) {
$path-stack($depth)($name)
};
declare %private function local:eq-path-with-positions($current-path as xs:QName*, $path-stack as map(xs:integer, map(xs:QName, xs:integer)), $path-with-positions as xs:string) as xs:boolean {
let $current-path-with-positions :=
'/' || string-join(
for $step-qn at $depth in $current-path
let $occurence := local:get-occurence($step-qn, $depth, $path-stack)
let $occurence-predicate-str := '[' || $occurence || ']'
return
$step-qn || $occurence-predicate-str
, '/'
)
return
$path-with-positions eq $current-path-with-positions
};
declare %private function local:replace($node as node(), $replace as xs:string, $replacement as element(), $current-path as xs:QName*, $path-stack as map(xs:integer, map(xs:QName, xs:integer))) as node() {
typeswitch($node)
case document-node()
return
document {
$node/node() ! local:replace(., $replace, $replacement, $current-path, $path-stack)
}
case element()
return
let $new-path := ($current-path, node-name($node))
let $new-path-stack :=
if(map:size($path-stack) eq 0) then
local:push-element($path-stack, $node, count($new-path))
else
$path-stack
return
let $matched-for-replace := local:eq-path-with-positions($new-path, $new-path-stack, $replace)
return
if($matched-for-replace)then
$replacement
else
element {name($node)} {
$node/#*,
local:children($node/node(), $replace, $replacement, $new-path, $new-path-stack)
}
default return $node
};
declare function local:replace($node as node(), $replace as xs:string, $replacement as element()) as node() {
let $path-stack as map(xs:integer, map(xs:QName, xs:integer)) := map {}
return
local:replace($node, $replace, $replacement, (), $path-stack)
};
let $doc :=
<fo:Test xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:books>
<!-- These are my books -->
<book title='xQuery for Dummys'>
<author>Jack Wizard</author>
<details>
<pages>221</pages>
</details>
</book>
<book title='Mysteries of xQuery'>
<author>Lost Linda</author>
<details>
<replace-this>Goodbye World!</replace-this>
<pages>40</pages>
</details>
</book>
</fo:books>
</fo:Test>
return
local:replace($doc, '/fo:Test[1]/fo:books[1]/book[2]/details[1]/pages[1]', <replaced>Hello World!</replaced>)

Related

Custom chunk implementation

Is it possible to customize the chunk configuration in Filepond such that the chunk information is provided to the upload server:
as query parameters instead of headers
with custom query parameter names instead of Upload-Length, Upload-Name, and Upload-Offset
I am trying to fit Filepond's chunk implementation to a third party upload endpoint that I don't have control over.
I have found the Advanced configuration where you provide a process function which I've played with a little bit to see what comes through the options param -- however that appears (I think) to make the chunking calculations my responsibility. My original thought was to manipulate the options.chunkServer.url to include the query params I need but I don't believe this processes individual chunks.
In case it makes a difference, this is being done in React using the react-filepond package.
I made and implementation in Laravel 6 using Traits and some "bad practices" (I didn't have time because ... release in prod) to join chunks into a file
Basically:
post to get unique id folder to storage
get chunks and join together
profit!
Here's the full code:
<?php
namespace App\Http\Traits\Upload;
use Closure;
use Faker\Factory as Faker;
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
trait Uploadeable
{
public function uploadFileInStorage(Request $request, Closure $closure)
{
// get the nex offset for next chunk send
if (($request->isMethod('options') || $request->isMethod('head')) && $request->has('patch')) {
//get the temp dir
$dir = $request->patch . DIRECTORY_SEPARATOR;
// reead all chunks in directory
$patch = collect(Storage::files($dir))
->sortBy(function ($file) {
return Storage::lastModified($file);
});
// read offsets for calculate
$offsets = array();
$size = 0;
$last_offset = 0;
foreach ($patch as $filename) {
$size = Storage::size($filename);
list($dir, $offset) = explode('file.patch.', $filename, 2);
array_push($offsets, $offset);
if ($offset > 0 && !in_array($offset - $size, $offsets)) {
$last_offset = $offset - $size;
break;
}
// last offset is at least next offset
$last_offset = $offset + $size;
}
// return offset
return response($last_offset, 200)
->header('Upload-Offset', $last_offset);
}
// chunks
if ($request->isMethod('patch') && $request->has('patch')) {
// get the temp dir
$dir = $request->patch . DIRECTORY_SEPARATOR;
// read headers
$offset = $request->header('upload-offset');
$length = $request->header('upload-length');
// should be numeric values, else exit
if (!is_numeric($offset) || !is_numeric($length)) {
return response('', 400);
}
// get the file name
$name = $request->header('Upload-Name');
// sleep server for get a diference between file created to sort
usleep(500000);
// storage the chunk with name + offset
Storage::put($dir . 'file.patch.' . $offset, $request->getContent());
// calculate total size of patches
$size = 0;
$patch = Storage::files($dir);
foreach ($patch as $filename) {
$size += Storage::size($filename);
}
// make the final file
if ($size == $length) {
// read all chunks in directory
$files = collect(Storage::files($dir))
->sortBy(function ($file) {
return Storage::lastModified($file);
});
// create output file
//Log::info(storage_path('app'));
$new_file_name = $final_name = trim(storage_path('app') . DIRECTORY_SEPARATOR . $dir . $name);
$file_handle = fopen($new_file_name, 'w');
// write patches to file
foreach ($files as $filename) {
// get offset from filename
list($dir, $offset) = explode('.patch.', $filename, 2);
// read chunk
$patch_handle = fopen(storage_path('app') . DIRECTORY_SEPARATOR . trim($filename), 'r');
$patch_contents = fread($patch_handle, filesize(storage_path('app') . DIRECTORY_SEPARATOR . trim($filename)));
fclose($patch_handle);
// apply patch
fseek($file_handle, $offset);
fwrite($file_handle, $patch_contents);
}
// done with file
fclose($file_handle);
// file permission (prefered 0755)
chmod($final_name, 0777);
// remove patches
foreach ($patch as $filename) {
$new_file_name = storage_path('app') . DIRECTORY_SEPARATOR . trim($filename);
unlink($new_file_name);
}
// simple class (no time to explain)
$file = new UploadedFile(
$final_name,
basename($final_name),
mime_content_type($final_name),
filesize($final_name),
false
);
$dir = $request->patch . DIRECTORY_SEPARATOR;
$object = new \stdClass();
$object->full_path = (string)$file->getPathname();
$object->directory = (string)($dir);
$object->path = (string)($dir . basename($final_name));
$object->name = (string)$file->getClientOriginalName();
$object->mime_type = (string)$file->getClientMimeType();
$object->extension = (string)$file->getExtension();
$object->size = (string)$this->formatSizeUnits($file->getSize());
// exec closure
$closure($file, (object)$object, $request);
}
// response
return response()->json([
'message' => 'Archivo subido correctamente.',
'filename' => $name
], 200);
}
// get dir unique id folder temp
if ($request->isMethod('post')) {
$faker = Faker::create();
$unique_id = $faker->uuid . '-' . time();
$unique_folder_path = $unique_id;
// create directory
Storage::makeDirectory($unique_folder_path);
// permisos directorio
chmod(storage_path('app') . DIRECTORY_SEPARATOR . $unique_folder_path . DIRECTORY_SEPARATOR, 0777);
// response with folder
return response($unique_id, 200)
->header('Content-Type', 'text/plain');
}
}
private function formatSizeUnits($bytes)
{
if ($bytes >= 1073741824) {
$bytes = number_format($bytes / 1073741824, 2) . ' GB';
} elseif ($bytes >= 1048576) {
$bytes = number_format($bytes / 1048576, 2) . ' MB';
} elseif ($bytes >= 1024) {
$bytes = number_format($bytes / 1024, 2) . ' KB';
} elseif ($bytes > 1) {
$bytes = $bytes . ' bytes';
} elseif ($bytes == 1) {
$bytes = $bytes . ' byte';
} else {
$bytes = '0 bytes';
}
return $bytes;
}
}
ยดยดยด

How to add another array value in codeigniter using getRecords

The orignial code was like this , I want to get landline_no value also in getRecords, How to do that
public function checklead() {
$lead = $_POST['number'];
$check = $this->common_model->getRecords('leads',array("phone_no"=>$lead));
if(count($check) > 0) {
$lead = $this->common_model->getRecored_row('leads',array("phone_no"=>$lead));
if($lead->assignto_self != 0) {
$assignto = $lead->assignto_self;
$key = 'Self Assign';
} else if($lead->assignto_se != 0) {
$assignto = $lead->assignto_se;
$key = '';}
What I have achieved so far,but not getting array values from getRecords
$lead = $_POST['number'];
$check = $this->common_model->getRecords('leads',array("phone_no"=>$lead),array("landline_no"=>$lead));
//echo "<pre>";
//print_r($check);
//echo $check[0]['landline_no'];exit;
if(count($check) > 0) {
$lead = $this->common_model->getRecored_row('leads',array("phone_no"=>$lead,"landline_no"=>$check[0]['landline_no']));
Code for getRecords:
function getRecords($table,$db = array(),$select = "*",$ordercol = '',$group = '',$start='',$limit=''){
$this->db->select($select);
if(!empty($ordercol)){
$this->db->order_by($ordercol);
}
if($limit != '' && $start !=''){
$this->db->limit($limit,$start);
}
if($group != ''){
$this->db->group_by($group);
}
$q=$this->db->get_where($table, $db);
return $q->result_array();
}
// Get Recored row
public function getRecored_row($table,$where)
{
$q = $this->db->where($where)
->select('*')
->get($table);
return $q->row();
}
Check my answer: This code also working well, i have written, but i am not sure , this logic is correct or not kindly check this one.
public function checklead() {
$lead = $_POST['number'];
if($this->common_model->getRecords('leads',array("phone_no"=>$lead)))
{
$check=$this->common_model->getRecords('leads',array("phone_no"=>$lead));
}
else
{
$check=$this->common_model->getRecords('leads',array("landline_no"=>$lead));
}
echo "<pre>";
//echo $check;
//print_r($check); exit;
$p= $check[0]['phone_no'];
$l= $check[0]['landline_no'];
// exit;
if(count($p) > 0 || count($l)>0) {
$lead = $this->common_model->getRecored_row('leads',array("phone_no"=>$p));
$lead1 = $this->common_model->getRecored_row('leads',array("landline_no"=>$l));
if($lead->assignto_self != 0 || $lead1->assignto_self != 0) {
$assignto = $lead->assignto_self;
$key = 'Self Assign';
} else if($lead->assignto_se != 0 || $lead1->assignto_se != 0) {
$assignto = $lead->assignto_se;
$key = '';
}else if($lead->assignto_tl != 0 || $lead1->assignto_tl != 0) {
$assignto = $lead->assignto_tl;
$key = '';
} else if($lead->uploaded_by != 0 || $lead1->uploaded_by != 0) {
$assignto = $lead->uploaded_by;
$key = 'Uploaded by';
}
$user = $this->common_model->getRecored_row('admin',array("id"=>$assignto));
$role = $this->common_model->getRecored_row('role',array("id"=>$user->role));
$this->session->set_flashdata('message', array('message' => 'This Lead Already exist with '.$user->name.' ('.$role->role.') '.' ','class' => 'danger'));
redirect(base_url().'leads');
} else {
redirect(base_url().'leads/add_newlead/'.$lead);
}
}
There does not seem to be any reason to use getRecords(). The $check value has no useful purpose and creating it is a waste of resources.
We don't need $check because getRecord_row() will return the "lead" if found so the only check needed is to see if getRecord_row() returns anything. getRecord_row() uses the database function row() which returns only one row or null if no rows are found. Read about row() here.
If what you want is to find the "lead" that has either a "phone_no" or a "landline_no" equal to $_POST['number'] then you need to use a custom string for the where clause. (See #4 at on this documentation page.) You need a custom string because getRecord_row() does not allow any other way to ask for rows where a='foo' OR b='foo'. Here is what I think you are looking for.
public function checklead()
{
// use input->post() it is the safe way to get data from $_POST
$phone = $this->input->post('number');
// $phone could be null if $_POST['number'] is not set
if($phone)
{
$lead = $this->common_model->getRecored_row('leads', "phone_no = $phone OR landline_no = $phone");
// $lead could be null if nothing matches where condition
if($lead)
{
if($lead->assignto_self != 0)
{
$assignto = $lead->assignto_self;
$key = 'Self Assign';
}
else if($lead->assignto_se != 0)
{
$assignto = $lead->assignto_se;
$key = '';
}
}
}
}
The main difference between getRecords() and getRecord_row() is the number of records (rows of data) to return. getRecord_row() will return a maximum of one record while getRecords() might return many records.
getRecords() accepts arguments that allow control of what data is selected ($db, $select), how it is arranged ($ordercol, $group), and the number of rows to retrieve ($limit) starting at row number x ($start) .

why we use $this__("Some text") instead simple echo magento

I am working with magento and have a question in mind that why we use $this__("Some text") instead simple echo magento. can anyone ?
When you call
echo $this->__("some text");
You can start by looking at Mage_Core_Helper_Abstract
/**
* Translate
*
* #return string
*/
public function __()
{
$args = func_get_args();
$expr = new Mage_Core_Model_Translate_Expr(array_shift($args), $this->_getModuleName());
array_unshift($args, $expr);
return Mage::app()->getTranslator()->translate($args);
}
Next is Mage_Core_Model_App
/**
* Retrieve translate object
*
* #return Mage_Core_Model_Translate
*/
public function getTranslator()
{
if (!$this->_translator) {
$this->_translator = Mage::getSingleton('core/translate');
}
return $this->_translator;
}
Which is handed to Mage_Core_Model_Translate
/**
* Translate
*
* #param array $args
* #return string
*/
public function translate($args)
{
$text = array_shift($args);
if (is_string($text) && ''==$text
|| is_null($text)
|| is_bool($text) && false===$text
|| is_object($text) && ''==$text->getText()) {
return '';
}
if ($text instanceof Mage_Core_Model_Translate_Expr) {
$code = $text->getCode(self::SCOPE_SEPARATOR);
$module = $text->getModule();
$text = $text->getText();
$translated = $this->_getTranslatedString($text, $code);
}
else {
if (!empty($_REQUEST['theme'])) {
$module = 'frontend/default/'.$_REQUEST['theme'];
} else {
$module = 'frontend/default/default';
}
$code = $module.self::SCOPE_SEPARATOR.$text;
$translated = $this->_getTranslatedString($text, $code);
}
//array_unshift($args, $translated);
//$result = #call_user_func_array('sprintf', $args);
$result = #vsprintf($translated, $args);
if ($result === false) {
$result = $translated;
}
if ($this->_translateInline && $this->getTranslateInline()) {
if (strpos($result, '{{{')===false || strpos($result, '}}}')===false || strpos($result, '}}{{')===false) {
$result = '{{{'.$result.'}}{{'.$translated.'}}{{'.$text.'}}{{'.$module.'}}}';
}
}
return $result;
}
which returns the resulting text. This is a quick walkthrough of how everything would be handled, you should view the classes themselves to get a more in-depth understanding.
In simple when you call echo $this->__('some text') it look up same
text in CSV file which is located in
app>locale
or
app>design>frontend>YOUR_PACKAGE>YOUR_THEME_NAME>locale>translate.csv
file if the same word exist then it translate a word
means it is very useful in multi-language website
$this->__("Some text")
Used for translation purpose

Why trie is also called "prefix tree"?

I was reading this article on Wikipedia and stumbled on the line which says "trie is also called prefix tree".
I know the usage of trie but why is it called "prefix tree"?
As they can be searched by prefixes. You can also reverse the trie and find wildcards: http://phpir.com/tries-and-wildcards.
For example the term academic would be c-i-m-e-d-a-c-a. Using the same
technique as before we can now search for all words that end with a
certain phrase, allowing us to handle wildcards at the beginning of
query terms, e.g. *cademically.
<?php
function buildTries($words) {
$trie = new Trie();
$rtrie = new Trie();
foreach($words as $word) {
$trie->add($word);
$rtrie->add(strrev($word));
}
return array('trie' => $trie, 'rtrie' => $rtrie);
}
function searchTries($search, $tries) {
$terms = explode('*', $search);
if(count($terms) > 2) {
return false;
}
if(strlen($terms[0]) && strlen($terms[0])) {
// middle wildcard
$straight = $tries['trie']->prefixSearch($terms[0]);
$rev = $tries['rtrie']->prefixSearch(strrev($terms[1]));
return array_intersect($straight, reverseArray($rev));
} else if(strlen($terms[1]) ) {
// leading wildcard
return reverseArray($tries['rtrie']->prefixSearch(strrev($terms[1])));
} else {
// trailing wildcard
return $tries['trie']->prefixSearch($terms[0]);
}
}
function reverseArray($keys) {
$return = array();
foreach($keys as $key => $value) {
$return[strrev($key)] = $value;
}
return $return;
}
/* Do some searches */
$words = array(
'adder',
'addled',
'abject',
'agreement',
'astronaut',
'handily',
'happily',
'helpfully'
);
$tries = buildTries($words);
$return = searchTries('h*ly', $tries);
var_dump($return);
$return = searchTries('ha*ly', $tries);
var_dump($return);
?>
The results from the two var dumps look like this:
array(3) {
["handily"]=>
NULL
["happily"]=>
NULL
["helpfully"]=>
NULL
}
array(2) {
["handily"]=>
NULL
["happily"]=>
NULL
}

Codeigniter: How to declare a global variable for a recursive function, and how to return it?

I want to use recursion in a model in Codeigniter, and am baffled as to where I should declare the global variable to be used in the recursive function.
I'm trying to show a catalog of products, ordered by their geographical classification. The recursion is needed because the geographical database is a hierarchy tree, where a place can have sons, grandsons, great-grandsons etc (for example: London is the son of England, which is the son of Britain, which is the son of Europe).
At the end of the recursion, I want to return the variable $arrCatalog, which will hold all the products. So my other question is how to return that variable in the end?
Here is my code (not tested yet, because I didn't know how to handle the global variable):
class Catalogs_model extends CI_Model {
public function __construct()
{
parent::__construct();
}
function getCatalog($place_id, $prod_type)
{
$sql =
"SELECT id, heb_name, type FROM places p
INNER JOIN places_relations r ON p.id = r.son
WHERE father = ?
ORDER BY sort_name";
$query = $this->db->query($sql, $place_id);
if($query->num_rows() > 0) {
foreach ($query->result() as $place) {
$sql2 =
"SELECT code, heb_title, price, place_id FROM products
INNER JOIN products_places ON prod_code=code
WHERE place_id = ? AND prod_type = ?";
$query2 = $this->db->query($sql, $place_id, $prod_type);
if($query2->num_rows() > 0) {
foreach ($query2->result() as $product) {
$arrCatalog[] = $product; // $arrCatalog is the global variable I don't know where to declare and how to return.
}
$this->getCatalog($place['id'], $prod_type);
}
}
}
}
}
Pass your variable to the current object ($this), then you can pass it around your model or hand it to a controller.
class Catalogs_model extends CI_Model {
public $arrCatalog = array();
public function __construct() {
parent::__construct();
}
function getCatalog($place_id, $prod_type) {
$sql = "SELECT ...";
$query = $this->db->query($sql, $place_id);
if($query->num_rows() > 0) {
foreach ($query->result() as $place) {
$sql2 = "...";
$query2 = $this->db->query($sql, $place_id, $prod_type);
if($query2->num_rows() > 0) {
foreach ($query2->result() as $product) {
$this->arrCatalog[] = $product;
}
$this->getCatalog($place['id'], $prod_type);
}
}
}
}
Your controller:
$this->catalogs_model->getCatalog(2, 'hebBook');
$data['data_rows'] = $this->catalogs_model->arrCatalog;
Testing, alter your model like so ....
class Catalogs_model extends CI_Model {
public $arrCatalog = array();
// add these variables for testing ....
private $greeting = 'Hello'; // notice this is private? You cannot access this from your controller but you can from anywhere within the Catalogs_model class.
public $output = ''; // public
public $string = null; // public
// your existing code ...
function hello ()
{
$this->output = $this->greeting;
}
function hello_string ()
{
if($this->string)
{
$this->output = $this->greeting.' '.$string;
}
}
} // end class
Now test in your controller
$this->catalogs_model->hello(); // runs the hello function which sets the model->output
echo $this->catalogs_model->output; // echos 'Hello'
echo '<br />'; // just so the output stands apart in your browser.
$this->catalogs_model->string = 'World!';
$this->catalogs_model->hello_string();
echo $this->catalogs_model->output; // echos Hello World!

Resources