2

I am just starting with Joomla component development and MVC in general. Im also not incredibly strong in PHP but I am trying to build a component that gets json and displays it as a jQuery accordion list.

I started by creating a PHP script that does just that and it works fine.

Now Im on the component part and the mvc is tripping me up. I adapted the hello world component in the docs tutorial found here: http://docs.joomla.org/Developing_a_Model-View-Controller_Component/3.1/Introduction

But when I install the component and go to my component I get:

Fatal error: Call to undefined function getProject() in /[path to joomla]/components/com_insightly/views/insightly/view.html.php on line 23

So my view cant use a function I defined in my model. I must be missing something because I thought the controller assigned the model to the view auto-magically.

Here is some source, (sorry im not indenting 8 spaces on each line manually)

site\models\insightly.php

// import Joomla modelitem library
jimport('joomla.application.component.modelitem');


class InsightlyModelInsightly extends JModelItem
{

public function getProject($user_id)
{

    $project_url = 'https://api.insight.ly/v2/projects/'.$user_id;
    $project = array();
    $html_tag = null;
    $html_class = null;
    $html_id = null;

    $curl = curl_init($project_url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json',
            'Authorization: Basic NotGonnaShareThatNowAmI')
    );
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

    $curl_response = curl_exec($curl);
    if ($curl_response){
        $decoded = json_decode($curl_response, true);
        $i = 0;
        foreach ($decoded as $key=>$value){
            // Eliminates Empty Fields and Saves to Multi-Dimensional Array
            if ($value){
                $value = id_mask($value);
            }
            switch($key)
            {
                case "PROJECT_NAME":
                    $key = null;
                    $html_tag = "h1";
                    break;
                case "STATUS":
                    $key = "Status";
                    $html_tag = "li";
                    break;
                case "PROJECT_DETAILS":
                    $key = "Description";
                    $html_tag = "li";
                    break;
                case "RESPONSIBLE_USER_ID":
                    $key = "Project Manager";
                    $html_tag = "li";
                    break;
                case "CATEGORY_ID":
                    $key = "Category";
                    $html_tag = "li";
                    break;
                default:
                    $value = null;
            }
            if ($value){
                $field = [$key, $value, $html_tag, $html_class, $html_id];
                $project[$i] = $field;
                $i++;
            }
        }

        return $project;
    }
    else {
        die('An error occurred retrieving Projects. Additional info: ' . curl_error($curl));
    }
    curl_close($curl);
}

public function getActiveTasks($user_id){

    $project_tasks = getTasks($user_id);
    $tasks = loopAndFind($project_tasks, 'STATUS', 'IN PROGRESS');
    $i = 0;
    foreach ($tasks as $key=>$value){
        $active_tasks[$i] = taskStyler($key, $value);
        $i++;
    }

    return $active_tasks;
}

public function getCompletedTasks($user_id){

    $project_tasks = getTasks($user_id);
    $tasks = loopAndFind($project_tasks, 'STATUS', 'COMPLETED');
    $i = 0;
    foreach ($tasks as $key=>$value){
        $completed_tasks[$i] = taskStyler($key, $value);
        $i++;
    }
    return $completed_tasks;
}

function getTasks($user_id){

    $task_url = 'https://api.insight.ly/v2/tasks';

    $curl = curl_init($task_url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json',
            'Authorization: Basic NotGonnaShareThatNowAmI')
    );
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

    $curl_response = curl_exec($curl);
    if ($curl_response){
        $decoded = json_decode($curl_response, true);
        $project_tasks = loopAndFind($decoded, 'PROJECT_ID', $user_id);
        return $project_tasks;
    }
    else {
        die('An Error occurred retrieving Tasks. Additional info: ' . curl_error($curl));
    }
    curl_close($curl);
}

//Search Tool for Multi-Dimensional Arrays
function loopAndFind($array, $index, $search){
    $returnArray = array();
    foreach($array as $k=>$v){
        if($v[$index] == $search){
            $returnArray[] = $v;
        }
    }
    return $returnArray;
}

//Formats dates as d/m/Y and removes the time
function date_formatter($value){
    date_default_timezone_set('America/New_York');
    $date = date_create($value);
    $value = date_format($date, "m/d/Y");
    return $value;
}

//Returns array with ALLCAPS corrected and html tags
function taskStyler ($key, $value){
    $html_tag = "li";
    $html_class = null;
    $html_id = null;

    switch ($key)
    {
        case "Title":
            $key = "Task";
            $html_tag = "h3";
            break;
        case "DUE_DATE":
            $key = "Due Date";
            $value = date_formatter($value);
            break;
        case "COMPLETED_DATE_UTC":
            $key = "Date Completed";
            $value = date_formatter($value);
            break;
        case "DETAILS":
            $key = "Details";
            $value = strip_tags($value);
            break;
        case "STATUS":
            $key = "Status";
            break;
        case "PERCENT_COMPLETE":
            $key = "Percent Complete";
            $value = $value . "%";
            break;
        case "START_DATE":
            $key = "Start Date";
            $value = date_formatter($value);
            break;
        case "RESPONSIBLE_USER_ID":
            $key = "Assigned to";
            $value = id_mask($value);
            break;
        default:
            $value = null;
    }
    if ($value){
        $task = [$key, $value, $html_tag, $html_class, $html_id];
    }
    else {
        $task = null;
    }
    return $task;
}
}

site\views\insightly\view.html.php

// import Joomla view library
jimport('joomla.application.component.view');

/**
* HTML View class for the Insightly Component
*/

class InsightlyViewInsightly extends JViewLegacy
{

// Overwriting JView display method
function display($tpl = null)
{
    $user =& JFactory::getUser();
    $user_id = $user->get( 'id' );
    $user_id= "765727";     //Set for Development

    // Assign data to the view
    $this->project = getProject($user_id);
    $this->active_tasks = getActiveTasks($user_id);
    $this->completed_tasks = getCompletedTasks($user_id);


    parent::display($tpl);
}
}

controller.php (which is empty)

// import Joomla controller library
jimport('joomla.application.component.controller');

/**
* Insightly Component Controller
*/
class InsightlyController extends JControllerLegacy
{
}

site\insightly.php

<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');

// import joomla controller library
jimport('joomla.application.component.controller');

// Get an instance of the controller prefixed by Insightly
$controller = JControllerLegacy::getInstance('Insightly');

// Perform the Request task
$input = JFactory::getApplication()->input;
$controller->execute($input->getCmd('task'));

// Redirect if set by the controller
$controller->redirect();

site\views\insightly\tmpl\default.php

<article id='project'>
<?php
$iterations = count($this->project);
for ($i = 0; $i <= $iterations; $i++) {
    echo('<' . $this->project[2]);
    if (isset($this->project[3])) {
        echo('class ="' . $this->project[3]);
    }
    if (isset($this->project[4])) {
        echo('class ="' . $this->project[4]);
    }
    echo('>');
    echo($this->project[0]);
    echo(' : ');
    echo($this->project[1]);
    echo('</' . $this->project[2] . '>');
}

?>
<div id='tasks'>
    <h2>Active Tasks</h2>
    <section class='tasks'>
        <?php
        $number_of_tasks = count($this->active_tasks);
        for ($i = 0; $i <= $number_of_tasks; $i++) {
            $task_iterations = count($this->active_tasks[$i]);
            for ($i = 0; $i <= $task_iterations; $i++) {
                echo('<' . $this->active_tasks[$i][2]);
                if (isset($this->active_tasks[$i][3])) {
                    echo('class ="' . $this->active_tasks[$i][3]);
                }
                if (isset($this->active_tasks[$i][4])) {
                    echo('class ="' . $this->active_tasks[$i][4]);
                }
                echo('>');
                echo($this->active_tasks[$i][0]);
                echo(' : ');
                echo($this->active_tasks[$i][1]);
                echo('</' . $this->active_tasks[$i][2] . '>');
            }
        }
        ?>
    </section>
    <h2>Completed Tasks</h2>
    <section class='tasks'>
        <?php
        $number_of_tasks = count($this->completed_tasks);
        for ($i = 0; $i <= $number_of_tasks; $i++) {
            $task_iterations = count($this->completed_tasks[$i]);
            for ($i = 0; $i <= $task_iterations; $i++) {
                echo('<' . $this->completed_tasks[$i][2]);
                if (isset($this->completed_tasks[$i][3])) {
                    echo('class ="' . $this->completed_tasks[$i][3]);
                }
                if (isset($this->completed_tasks[$i][4])) {
                    echo('class ="' . $this->completed_tasks[$i][4]);
                }
                echo('>');
                echo($this->completed_tasks[$i][0]);
                echo(' : ');
                echo($this->completed_tasks[$i][1]);
                echo('</' . $this->completed_tasks[$i][2] . '>');
            }
        }
        ?>
    </section>
</div>
</article>

<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<script>
    $(function () {
        $(".tasks").accordion({ collapsible: true, active: false });
    });
</script>

Any insight on why I cant get to my models function? Also I welcome the pointing out of any other blaring mistakes and security flaws.

EDIT: the idMask function was removed in my post due to sensitive content. It is probably not the issue.

EDIT: I have the component loading now and have updated the code but I'm having trouble with the arrays. taskStyler should return an array to be set to $completed_tasks[i].

completed_tasks[0][0] is correct but completed_tasks[0][1] contains an array composed of what should becompleted_tasks[0][1-12].

This is my current version of the relevant functions:

Calls getTasks and compiles array of tasks that are in progress

public function getActiveTasks($user_id){

    $project_tasks = $this->getTasks($user_id);
    $tasks = $this->loopAndFind($project_tasks, 'STATUS', 'IN PROGRESS');
    $i = 0;
    foreach ($tasks as $key=>$value){
            $active_tasks[$i] = $this->taskStyler($key, $value);
            $i++;
    }
    return $active_tasks;
}

Calls getTasks and compiles array of tasks that are completed

public function getCompletedTasks($user_id){

    $project_tasks = $this->getTasks($user_id);
    $tasks = $this->loopAndFind($project_tasks, 'STATUS', 'COMPLETED');
    $i = 0;
    foreach ($tasks as $key=>$value){
            $completed_tasks[$i] = $this->taskStyler($key, $value);
            $i++;
    }
    return $completed_tasks;
}

Curl session with API server that returns an array of tasks (known to work perfectly)

public function getTasks($user_id){

    $task_url = 'https://api.insight.ly/v2/tasks';

    $curl = curl_init($task_url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json',
            'Authorization: Basic Dontlookatmypassword')
    );
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

    $curl_response = curl_exec($curl);
    if ($curl_response){
        $decoded = json_decode($curl_response, true);
        $project_tasks = $this->loopAndFind($decoded, 'PROJECT_ID', $user_id);
        return $project_tasks;
    }
    else {
        die('An Error occurred retrieving Tasks. Additional info: ' . curl_error($curl));
    }
    curl_close($curl);
}

Returns an array representing a datafield of a task with the keys and some values edited for readability, and html tags, classes and ids appended.

public function taskStyler ($key, $value){
    $html_tag = "li";
    $html_class = null;
    $html_id = null;

    switch ($key)
    {
        case "Title":
            $key = "Task";
            $html_tag = "h3";
            break;
        case "DUE_DATE":
            $key = "Due Date";
            $value = $this->dateFormatter($value);
            break;
        case "COMPLETED_DATE_UTC":
            $key = "Date Completed";
            $value = $this->dateFormatter($value);
            break;
        case "DETAILS":
            $key = "Details";
            $value = strip_tags($value);
            break;
        case "STATUS":
            $key = "Status";
            break;
        case "PERCENT_COMPLETE":
            $key = "Percent Complete";
            $value = $value . "&#37;";
            break;
        case "START_DATE":
            $key = "Start Date";
            $value = $this->dateFormatter($value);
            break;
        case "RESPONSIBLE_USER_ID":
            $key = "Assigned to";
            $value = $this->idMask($value);
            break;
        default:
            $value = null;
    }
    if ($value) {
        $task = [$key, $value, $html_tag, $html_class, $html_id];
    }
    else{ $task = null;
    }
    return $task;
}
2

The problem is in your view.

You can use $this->get('project'), which would call the getProject() method of your model. However it doesn't allow to pass an argument.

Thus in your case, you need to fetch the model first and the call the method on it:

$model   = $this->getModel();
$project = $model->getProject($user_id);
  • I was also missing a $this-> in front of EVERY function call in the method and view. -Thank you. – John May 9 '14 at 19:43
  • 1
    @WishingWellIndustries you should accept Bakual's answer then – fruppel May 10 '14 at 6:38
  • I ended up creating a function in the model to get the user id, calling that within each get*Task function and getting the returned variable in the view. Keeps the view honest. – John May 13 '14 at 7:01
0

To pass params to your model functions add the below to your view display task

$model = $this->getModel();

Then prefix getProject() and the others with

$model->

Then you can pass params to the methods.

Happy Joomla!ng

  • Basically what @Bukual said. – John May 12 '14 at 14:54
  • Yep. I answered before I saw that part of his answer. Should have scrolled with Stackexchange mobile app. – Mathew Lenning May 13 '14 at 9:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.