Quantcast
Channel: Joomla! Forum - community, help and support
Viewing all articles
Browse latest Browse all 2350

Joomla! 5.x Coding • Plugin to notify users of new articles

$
0
0
Hi,

I need to write a plugin that will send an email to users to notify them of new published articles. And while I'm a C++ developer since almost 30 years, I am not experienced with PHP.

This is what the plugin needs to do:
  1. On installation, create a custom user field "Notify me of new articles". Should be a checkbox.
  2. When a new article is published, send an email to all users that have enabled "Notify me of new articles" in their profile.
Since I am also new to Joomla plugin development, I asked ChatGPT 4-o to get me started with code. But, not much to my surprise, the code it gave me does not work at all. The plugin installs without errors, and can be enabled, but it never does anything.

The manifest file

Code:

<?xml version="1.0" encoding="utf-8"?><extension type="plugin" group="system" version="5.0" method="upgrade">    <name>PLG_SYSTEM_NOTIFYNEWCONTENT</name>    <author>me</author>    <creationDate>2024-06-06</creationDate>    <copyright>(C) 2024 me</copyright>    <license>GNU General Public License version 2 or later; see LICENSE.txt</license>    <version>1.0.2</version>    <description>PLG_SYSTEM_NOTIFYNEWCONTENT_DESC</description>    <files>        <filename plugin="notifynewcontent">plg_system_notifynewcontent.php</filename>        <filename>install_script.php</filename>    </files>    <languages>        <language tag="en-GB">language/en-GB/en-GB.plg_system_notifynewcontent.ini</language>        <language tag="en-GB">language/en-GB/en-GB.plg_system_notifynewcontent.sys.ini</language>        <language tag="de-DE">language/de-DE/de-DE.plg_system_notifynewcontent.ini</language>        <language tag="de-DE">language/de-DE/de-DE.plg_system_notifynewcontent.sys.ini</language>    </languages>    <install>        <scriptfile>install_script.php</scriptfile>    </install></extension>
The install script
This should also create the user field "Notify me of new content" in the database. However, it does not. The plugin file is correctly copied to /plugins/system/notifynewcontent, though.

Code:

<?php// No direct accessdefined('_JEXEC') or die;use Joomla\CMS\Factory;use Joomla\CMS\Installer\InstallerScript;use Joomla\CMS\Language\Text;use Joomla\CMS\Log\Log;class PlgSystemNotifynewcontentInstallerScript extends InstallerScript{    public function preflight($type, $parent)    {        echo 'Install Preflight';        Log::add('Preflight action - Type: ' . $type, Log::NOTICE, 'install');    }    public function postflight($type, $parent)    {        echo 'Install Postflight';        Log::add('Postflight action - Type: ' . $type, Log::NOTICE, 'install');        if ($type == 'install') {            $this->addProfileField();        } elseif ($type == 'update') {            // Actions to perform after update        } elseif ($type == 'uninstall') {            $this->removeProfileField();        }    }    public function uninstall($parent)    {        echo 'uninstall()';        Log::add('Uninstall action', Log::NOTICE, 'install');        $this->removeProfileField();    }    protected function addProfileField()    {        echo 'addProfileField()';        Log::add('Adding profile field', Log::ERROR, 'install');        $db = Factory::getDbo();        $fieldTitle = Text::_('PLG_SYSTEM_NOTIFYNEWCONTENT_NOTIFY');        // Check if the field already exists        $query = $db->getQuery(true)            ->select('COUNT(*)')            ->from($db->quoteName('#_fields'))            ->where($db->quoteName('name') . ' = ' . $db->quote('notify_on_new_content'));        $db->setQuery($query);        if (!$db->loadResult())        {            Log::add('Field does not exist, creating new field', Log::NOTICE, 'install');            // Add the field            $query = $db->getQuery(true)                ->insert($db->quoteName('#_fields'))                ->columns(array(                    $db->quoteName('title'),                    $db->quoteName('name'),                    $db->quoteName('label'),                    $db->quoteName('type'),                    $db->quoteName('context'),                    $db->quoteName('state'),                    $db->quoteName('fieldparams'),                    $db->quoteName('created_time'),                    $db->quoteName('created_user_id')                ))                ->values(                    $db->quote($fieldTitle) . ', ' .                    $db->quote('notify_on_new_content') . ', ' .                    $db->quote($fieldTitle) . ', ' .                    $db->quote('radio') . ', ' .                    $db->quote('com_users.user') . ', ' .                    1 . ', ' .                    $db->quote(json_encode(array(                        'default' => '0',                        'options' => array(                            array('value' => '1', 'text' => 'Yes'),                            array('value' => '0', 'text' => 'No')                        )                    ))) . ', ' .                    $db->quote(Factory::getDate()->toSql()) . ', ' .                    $db->quote(Factory::getUser()->id)                );            $db->setQuery($query);            try {                $db->execute();                Log::add('Field created successfully', Log::NOTICE, 'install');            } catch (Exception $e) {                Log::add('Error creating field: ' . $e->getMessage(), Log::ERROR, 'install');            }        } else {            Log::add('Field already exists', Log::NOTICE, 'install');        }    }    protected function removeProfileField()    {        echo 'removeProfileField()';        Log::add('Removing profile field', Log::NOTICE, 'install');        $db = Factory::getDbo();        $query = $db->getQuery(true)            ->delete($db->quoteName('#_fields'))            ->where($db->quoteName('name') . ' = ' . $db->quote('notify_on_new_content'));        $db->setQuery($query);        try {            $db->execute();            Log::add('Field removed successfully', Log::NOTICE, 'install');        } catch (Exception $e) {            Log::add('Error removing field: ' . $e->getMessage(), Log::ERROR, 'install');        }    }}
The main plugin file
This should catch onContentAfterSave(), get a list of users that have the option "Notify me of new content" enabled, and then send the mail.

Code:

<?php// No direct accessdefined('_JEXEC') or die;use Joomla\CMS\Plugin\CMSPlugin;use Joomla\CMS\Factory;use Joomla\CMS\Language\Text;use Joomla\CMS\Uri\Uri;use Joomla\CMS\Router\Route;class PlgSystemNotifynewcontent extends CMSPlugin{    protected $app;    protected $db;    public function __construct(&$subject, $config)    {        parent::__construct($subject, $config);        $this->db = Factory::getDbo();    }    public function onContentAfterSave($context, $article, $isNew)    {        error_log('onContentAfterSave triggered');        if ($context == 'com_content.article' && $isNew)        {            error_log('New article detected');            $this->notifyUsers($article);        }    }    protected function notifyUsers($article)    {        // Get the field ID for 'notify_on_new_content'        $query = $this->db->getQuery(true)            ->select($this->db->quoteName('id'))            ->from($this->db->quoteName('#_fields'))            ->where($this->db->quoteName('name') . ' = ' . $this->db->quote('notify_on_new_content'));        $this->db->setQuery($query);        $fieldId = $this->db->loadResult();        if (!$fieldId)        {            error_log('Field "notify_on_new_content" not found.');            return;        }        // Get all users with the "Notify on new content" enabled        $query = $this->db->getQuery(true)            ->select($this->db->quoteName(array('u.email', 'u.name')))            ->from($this->db->quoteName('#_users', 'u'))            ->join('INNER', $this->db->quoteName('#_fields_values', 'fv') . ' ON ' . $this->db->quoteName('u.id') . ' = ' . $this->db->quoteName('fv.item_id'))            ->where($this->db->quoteName('fv.field_id') . ' = ' . (int) $fieldId)            ->where($this->db->quoteName('fv.value') . ' = ' . $this->db->quote('1'));        $this->db->setQuery($query);        $users = $this->db->loadObjectList();        error_log('Users to notify: ' . count($users));        // Get the category name        $categoryId = $article->catid;        $categoryQuery = $this->db->getQuery(true)            ->select($this->db->quoteName('title'))            ->from($this->db->quoteName('#_categories'))            ->where($this->db->quoteName('id') . ' = ' . (int) $categoryId);        $this->db->setQuery($categoryQuery);        $categoryName = $this->db->loadResult();        // Prepare email subject and body        $subject = Text::_('PLG_SYSTEM_NOTIFYNEWCONTENT_EMAIL_SUBJECT');        $bodyTemplate = Text::_('PLG_SYSTEM_NOTIFYNEWCONTENT_EMAIL_BODY');        // Generate SEF URL        $articleLink = Route::_(            'index.php?option=com_content&view=article&id=' . $article->id . ':' . $article->alias . '&catid=' . $article->catid . '&Itemid=' . $article->params->get('item_id')        , false);        // Format the publish date        $publishDate = (new \Joomla\CMS\Date\Date($article->publish_up))->format('d.m.Y');        $body = str_replace(            array('{ARTICLE_TITLE}', '{ARTICLE_CATEGORY}', '{ARTICLE_PUBLISH_DATE}', '{ARTICLE_LINK}'),            array($article->title, $categoryName, $publishDate, Uri::root() . $articleLink),            $bodyTemplate        );        error_log('Email body: ' . $body);        // Send email to each user        foreach ($users as $user)        {            $mail = Factory::getMailer();            $mail->addRecipient($user->email);            $mail->setSubject($subject);            $mail->setBody($body);            $mail->Send();            error_log('Email sent to: ' . $user->email);        }    }}
As you can see, I have put in quite a lot of echo, log, and error_log calls. However, none of these messages ever appears in any of the log files or in the page source. In my Joomla configuration, I have enabled debugging.

I am stumped, because nothing seems to do anything. I guess (there doesn't seem to be much more than guessing with PHP) none of the plugin code is ever executed.

I would appreciate some help, and thank you in advance!

Cheers,
Frank

Statistics: Posted by frankw80 — Thu Jun 06, 2024 8:37 am



Viewing all articles
Browse latest Browse all 2350

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>