0

First of all, I'm quite new to creating my own modules and plugins (and very much in learning stages!) and I find the help here excellent and very inspirational - thank you.

I'm trying to create a plugin that displays a notification when a new article has been created in a chosen category. Eventually, the plugin will link to a module which will display a link to the newly created article.

I'm doing this in stages and so far, so good. However, onContentAfterSave returns all new articles from the chosen category, but I just want to display one, the newest.

Here's what I have so far:

public function onContentAfterSave ($context, $article, $isNew)
{
}

public function onContentPrepare($context, &$article, &$params)
{
    $category = $article->catid;
    $article_title = $article->title;

    $newarticlenotificationcategory = $this->params->get('newarticlenotificationcategory');

    $db = JFactory::getDbo();
    $query = $db->getQuery(true);
    $query = "
    SELECT * 
    FROM #__content 
    WHERE (title LIKE '$article_title')
    ORDER BY id DESC 
    LIMIT 1 
    ;";

    $db->setQuery($query);
    $results = $db->loadObjectList();

    if ($category == $newarticlenotificationcategory) 
    {
        echo '<h3 style="color:white;background:red">There is a new article called - ' . $article_title . ' - ID - ' . $results->id . ' - in category - ' . $category . ' .</h3>';
    }
}

Also, what do I have access to from $article and $isNew please?

Many thanks.

EDIT:

Thank you all for your answers and comments, it is appreciated. Based on everything I'm going to take the advice and scrap what I have and re-think my approach to this entirely. Once I have a working example of what I'm attempting to do I'll post an update here. Again, thanks everyone.

3
  • Hi JJBW! When you say so far, so good you refer to what? Have you got any results that show you are approaching your desired result by running your plugin?
    – FFrewin
    Commented Sep 24, 2019 at 17:56
  • Hi @FFrewin, please see my edit above. I'm creating the plugin in stages and I want to reduce the results to just one, the latest post.
    – JJBW
    Commented Sep 24, 2019 at 18:22
  • The body of your question seems to be about onContentPrepare but the title and in one instance you say onContentAfterSave so I am a bit confused.
    – Irata
    Commented Sep 24, 2019 at 21:54

3 Answers 3

3

I am reading your code and I think it makes no sense... I can see only problems in your question, the code and in the approach for what I assume you want to achieve.

I will try to translate what your code will be doing if you enable your plugin:

  • You will be running what you have there in every content load, for as many content items you will be loading each time with the onContentPrepare (think blog/list layouts as well).

  • You will have the category id of each article where the plugin will be running.

  • You will query the database to get the record of that same article from where your plugin will be running. Not sure if your query will be correct in terms of syntax - but definitely it makes no sense at all in terms of logic. (Can you tell what are you expecting to get back from that query? And why are you querying the DB at that point?)

  • So with your query you will end up with a result from the database which will be actually the same article as the $article of the event you are already running.

  • However, whatever the case with your DB Query - eventually it doesn't seem to make any difference as you just assign the results to a variable and you do nothing with them.

  • Well, OK, you just use somewhere something like $results->id; which there is no chance to be correct, given what the $results should look like after your assignment.

  • Finally you only check if the category (ID) of the current article (that the onContentPrepare runs from), is equal to the one set in the plugin's params. Then you echo something ...

Your code is far away from being a workable solution ... I think you need to re-think everything... Read my points above to realize what you current code is doing and re-work your solution. Come back if you need further help - but you have to reach to a more clear path/approach for what you are doing - or ask the right questions each time for each problem/stage you are in.

2

You could use this sample of code to have a peek at what is available from the data being passed to onContentAfterSave

    public function onContentAfterSave ($context, $article, $isNew)
    {
        echo "<pre> Context ......."; print_r($context);"</pre>";
        echo "<pre> Article ......."; print_r($article);"</pre>";
        echo "<pre> IsNew   ......."; print_r($isNew);"</pre>";

        echo "<pre> Article Id ......." . $article->id . "</pre>";

        die;
     }

$context contains an indentifier of what trigger the plugin and is normally used to only process calls from a component or module that your are interested. For example you would simply return to the caller anyone that is not $conext = 'com_content.article' .

$article has a whole lot of stuff you probably didn't know was available or would probably ever want but if you run the code and scroll to the bottom you can see the parts of the object that you will probably want to use.

Because it is a an Object you need to use '->' to access the data inside.

$isNew is just a flag to say it is a new record that has been saved.

1

There may be multiple issues to correct with your snippet, but I can confidently point out a couple things...

  1. (title LIKE '$article_title') This is seeking an exact match because there are no wildcard characters in the value to follow LIKE. Since your intention is probably to make an exact match, it is better programming to use = instead of LIKE. For that matter, it is recommended that you use Joomla's query building methods. If you have a title containing a single quote, your query will break because there is no escaping supplied. (Please refer to any of my [mysql] tagged answers for examples and explanations.)

  2. loadObjectList() creates a multidimensional object, but you are only expecting a single row in the results, so the most ideal result-gathering method to call is loadObject(). This will yield a one-dimensional (flat) object (this should work seamlessly with your <h3> content. That said, if you only want to extract id, then you can write SELECT id then call loadResult() to receive that lone value.

  3. As for MVC practices, you shouldn't be echoing content in the same place that you are querying the database -- but this is probably not a concern of yours at this point.

As you continue to develop your script, be sure to display your variables (for your own knowledge), so that you can see what is working and what isn't. This is very helpful to my development: https://docs.joomla.org/Display_error_messages_and_notices

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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