*

aviros

  • ***
  • 49 posts
The subscription to the search does not work
« on: January 18, 2026, 12:43:51 PM »
After updating Osklass to version v8.3.1, the search subscription stopped working. This means that the user does not receive emails if they are subscribed to a specific search. How can this be fixed?  :( :( :( :( :( :( :( :( :( :( :( :( :( :(

*

MB Themes

Re: The subscription to the search does not work
« Reply #1 on: January 18, 2026, 01:23:26 PM »
Do you have some logs?
  To get fast support, we need following details: Detail description, URL to reproduce problem, Screenshots

*

aviros

  • ***
  • 49 posts
Re: The subscription to the search does not work
« Reply #2 on: January 18, 2026, 01:47:23 PM »
No, there are no records, but I've stopped receiving subscription emails for the ! search. They used to come, but now they don't(((

*

aviros

  • ***
  • 49 posts
Re: The subscription to the search does not work
« Reply #3 on: January 18, 2026, 02:04:36 PM »
The user has just published an ad! And messages should be sent to two addresses because they have search subscriptions. They should be sent immediately, but the emails are not arriving, even though the cron job is triggering.  :(

*

aviros

  • ***
  • 49 posts
Re: The subscription to the search does not work
« Reply #4 on: January 18, 2026, 02:20:24 PM »
Here's the log I made, if that gives you any insight. I published an ad there, but no emails arrived at pepperexpress@rambler.ru and mehos2004@mail.ru

*

MB Themes

Re: The subscription to the search does not work
« Reply #5 on: January 19, 2026, 01:44:31 PM »
There is most probably typo in oc-includes/osclass/alerts.php

Fixed file (please test).
Code: [Select]
<?php
/*
 * Copyright 2014 Osclass
 * Copyright 2026 Osclass by OsclassPoint.com
 *
 * Osclass maintained & developed by OsclassPoint.com
 * You may not use this file except in compliance with the License.
 * You may download copy of Osclass at
 *
 *     https://osclass-classifieds.com/download
 *
 * Do not edit or add to this file if you wish to upgrade Osclass to newer
 * versions in the future. Software is distributed on an "AS IS" basis, without
 * warranties or conditions of any kind, either express or implied. Do not remove
 * this NOTICE section as it contains license information and copyrights.
 */


/**
 * @param null $type
 * @param null $last_exec
 */
 
function osc_runAlert($type null$last_exec null){
  
$mUser User::newInstance();
  if(!
in_array($type, array('HOURLY''DAILY''WEEKLY''INSTANT'))) {
    return;
  }

  if(
$last_exec == null) {
    
$cron Cron::newInstance()->getCronByType($type);
    
$last_exec '0000-00-00 00:00:00';
    
    if(
is_array($cron)) {
      
$last_exec $cron['d_last_exec'];
    }
  }

  
$internal_name 'alert_email_hourly';
  
  switch(
$type) {
    case 
'HOURLY':
      
$internal_name 'alert_email_hourly';
      break;
    case 
'DAILY':
      
$internal_name 'alert_email_daily';
      break;
    case 
'WEEKLY':
      
$internal_name 'alert_email_weekly';
      break;
    case 
'INSTANT':
      
$internal_name 'alert_email_instant';
      break;
  }

  
$active true;
  
$searches Alerts::newInstance()->findByTypeGroup($type$active);

  if(
is_array($searches) && count($searches) > 0) {
    foreach(
$searches as $s_search) {
      
// Get if there're new ads on this search
      
$json $s_search['s_search'];
      
$array_conditions = (array)@json_decode($jsontrue);

      
$new_search Search::newInstance();
      
$new_search->setJsonAlert($array_conditions$s_search['s_email'], $s_search['fk_i_user_id']);
      
$new_search->addConditions(sprintf(" %st_item.dt_pub_date > '%s' "DB_TABLE_PREFIX$last_exec));

      
$items $new_search->doSearch();
      
$totalItems $new_search->count();
      
      
$search_email = ($s_search['s_email'] ?? '');
      

      if(
$totalItems && is_array($items) && count($items) > 0) {
        
Log::newInstance()->insertLog(
          
'alerts',
          
'notifyUser',
          
$s_search['fk_i_user_id'],
          
sprintf(__('%d listings matched alert ID %d for user %s (ID %d)'), $totalItems$s_search['pk_i_id'], $s_search['s_email'], $s_search['fk_i_user_id']),
          
'cron',
          
0
        
);

        
Alerts::newInstance()->increaseTrigger($s_search['pk_i_id']);     // it's alert ID

        // If we have new items from last check
        // Catch the user subscribed to this search
        
$alerts Alerts::newInstance()->findUsersBySearchAndType($s_search['s_search'], $type$active);

        if(
is_array($alerts) && count($alerts) > 0) {
          
$ads '<table id="alert-items" cellspacing="0" cellpadding="8">';
          
          foreach(
$items as $item) {
            
$ads .= '<tr>';
            
$resource ItemResource::newInstance()->getResource($item['pk_i_id']);

            if(isset(
$resource['pk_i_id']) && $resource['pk_i_id'] > 0) {
              
$path osc_apply_filter('resource_path'osc_base_url().$resource['s_path']);
              
$img_link osc_apply_filter('resource_thumbnail_url'$path.$resource['pk_i_id']."_thumbnail.".$resource['s_extension']);
            } else {
              
$img_link osc_base_url() . 'oc-includes/osclass/gui/images/no_photo.gif';
            }

            
$ads .= '<td width="80" style="border-top:1px solid #ddd"><img src="' $img_link '" width="80"/></td>';
            
$ads .= '<td align="left" style="border-top:1px solid #ddd"><a href="' osc_item_url_ns($item['pk_i_id']) . '">' $item['s_title'] . '</a><br/><span>' osc_highlight($item['s_description'], 115) . '</span></td>';

            
$ads .= '</tr>';
          }

          
$ads .= '</table>';


          foreach(
$alerts as $alert) {
            if(!isset(
$alert['fk_i_user_id']) && !isset($alert['s_email'])) {
              continue;
            }
            
            
$user = array();
            
            
// Find user record
            
if($alert['fk_i_user_id'] > 0) {
              
$user $mUser->findByPrimaryKey($alert['fk_i_user_id']);
            } else {
              
$user $mUser->findByEmail($alert['s_email']);
            }
            
            
// User not found
            
if($user === false || !isset($user['pk_i_id'])) {
              
$user = array(
                
'pk_i_id'  => 0,
                
's_name'  => $alert['s_email'],
                
's_email' => $alert['s_email']
              );
            }
            
            
// Only trigger alert to non-banned users
            
if(osc_is_email_banned($user['s_email']) !== false) {
              
Log::newInstance()->insertLog(
                
'alerts',
                
'notifyUserBanned',
                
$s_search['fk_i_user_id'],
                
sprintf(__('Alert ID %d for user %s (ID %d) was not sent because the user\'s email is banned.'), $s_search['pk_i_id'], $s_search['s_email'], $s_search['fk_i_user_id']),
                
'cron',
                
0
              
);
              
              continue;
            }


            
// Trigger email
            // hook_alert_email_hourly, hook_alert_email_daily, hook_alert_email_weekly, hook_alert_email_instant
            
osc_run_hook('hook_' $internal_name$user$ads$alert$items$totalItems);
            
AlertsStats::newInstance()->increase(date('Y-m-d'));
          }
        }
      }
    }
  }
}
« Last Edit: January 19, 2026, 01:54:36 PM by MB Themes »
  To get fast support, we need following details: Detail description, URL to reproduce problem, Screenshots

*

aviros

  • ***
  • 49 posts
Re: The subscription to the search does not work
« Reply #6 on: January 19, 2026, 03:19:42 PM »
I rewrote the file as you instructed, but the paradox is that emails are now only being sent to one user: "pepperexpress@rambler.ru". Emails are not reaching others, even though the user mehos2004@mail.ru is also subscribed to receive them. Essentially, emails are now only being sent to a single recipient   :( :(

*

aviros

  • ***
  • 49 posts
Re: The subscription to the search does not work
« Reply #7 on: January 19, 2026, 03:22:43 PM »
I just tried to publish a listing and checked the mailboxes. Only "pepperexpress@rambler.ru" received a notification. The user "mehos2004@mail.ru" did not receive an email about the new listing being published.

*

aviros

  • ***
  • 49 posts
Re: The subscription to the search does not work
« Reply #8 on: January 19, 2026, 03:28:07 PM »
Immediately before updating to Osklass 8.3.1, I had the same problem in version 8.3.0. I thought updating to 8.3.1 would solve the issue, but alas.

*

aviros

  • ***
  • 49 posts
Re: The subscription to the search does not work
« Reply #9 on: January 19, 2026, 04:33:26 PM »
I've just attempted to publish the listing again using the username "pepperexpress@rambler.ru". The email notification was received by "zakaz@chibaoshop.ru" only, while "mehos2004@mail.ru" did not receive it. My understanding is that it's being sent to only one user, the one listed first, and not to the rest.

*

MB Themes

Re: The subscription to the search does not work
« Reply #10 on: January 19, 2026, 05:32:43 PM »
@aviros
Not 100% sure it works well.
Logic is bit strange:
- get ie daily alerts
- it has some search condition
- based on that condition, find if there is more users with identical alert

> Problem here could be, that items returned may use different dt_pub_date  .. as items in alerts are included only from specific pub date (based on alert trigger).



Try this one
Code: [Select]
<?php
/*
 * Copyright 2014 Osclass
 * Copyright 2026 Osclass by OsclassPoint.com
 *
 * Osclass maintained & developed by OsclassPoint.com
 * You may not use this file except in compliance with the License.
 * You may download copy of Osclass at
 *
 *     https://osclass-classifieds.com/download
 *
 * Do not edit or add to this file if you wish to upgrade Osclass to newer
 * versions in the future. Software is distributed on an "AS IS" basis, without
 * warranties or conditions of any kind, either express or implied. Do not remove
 * this NOTICE section as it contains license information and copyrights.
 */


/**
 * @param null $type
 * @param null $last_exec
 */
 

function osc_runAlert($type null$last_exec null){
  
$mUser User::newInstance();
  
  
$type strtoupper(trim((string)$type));
  if(!
in_array($type, array('HOURLY''DAILY''WEEKLY''INSTANT'))) {
    return;
  }

  if(
$last_exec == null) {
    
$cron Cron::newInstance()->getCronByType($type);
    
$last_exec '0000-00-00 00:00:00';
    
    if(
is_array($cron)) {
      
$last_exec $cron['d_last_exec'];
    }
  }

  
$internal_name 'alert_email_hourly';
  
  switch(
$type) {
    case 
'HOURLY':
      
$internal_name 'alert_email_hourly';
      break;
    case 
'DAILY':
      
$internal_name 'alert_email_daily';
      break;
    case 
'WEEKLY':
      
$internal_name 'alert_email_weekly';
      break;
    case 
'INSTANT':
      
$internal_name 'alert_email_instant';
      break;
  }

  
$active true;
  
$searches Alerts::newInstance()->findByTypeGroup($type$active);


  
// Some alerts are matched
  
if(is_array($searches) && count($searches) > 0) {
    foreach(
$searches as $s_search) {
      
// Get if there're new ads on this search
      
$json $s_search['s_search'];
      
$array_conditions = (array)@json_decode($jsontrue);

      
$new_search Search::newInstance();
      
$new_search->setJsonAlert($array_conditions$s_search['s_email'], $s_search['fk_i_user_id']);
      
$new_search->addConditions(sprintf(" %st_item.dt_pub_date > '%s' "DB_TABLE_PREFIX$last_exec));

      
$items $new_search->doSearch();
      
$totalItems $new_search->count();

      
// We've found some new listings
      
if(is_array($items) && count($items) > 0) {
        
// Log::newInstance()->insertLog(
          // 'alerts',
          // 'notifyUser',
          // $s_search['fk_i_user_id'],
          // sprintf(__('%d listings matched alert ID %d for user %s (ID %d)'), $totalItems, $s_search['pk_i_id'], $s_search['s_email'], $s_search['fk_i_user_id']),
          // 'cron',
          // 0
        // );


        // If we have new items from last check
        // Catch the user subscribed to this search - there could be more users with identical search so handle all of them
        
$alerts Alerts::newInstance()->findUsersBySearchAndType($s_search['s_search'], $type$active);

        if(
is_array($alerts) && count($alerts) > 0) {
          
$ads '<table id="alert-items" cellspacing="0" cellpadding="8">';

          foreach(
$items as $item) {
            
$ads .= '<tr>';
            
$resource ItemResource::newInstance()->getResource($item['pk_i_id']);

            if(isset(
$resource['pk_i_id']) && $resource['pk_i_id'] > 0) {
              
$path osc_apply_filter('resource_path'osc_base_url().$resource['s_path']);
              
$img_link osc_apply_filter('resource_thumbnail_url'$path.$resource['pk_i_id']."_thumbnail.".$resource['s_extension']);
            } else {
              
$img_link osc_base_url() . 'oc-includes/osclass/gui/images/no_photo.gif';
            }

            
$ads .= '<td width="80" style="border-top:1px solid #ddd"><img src="' $img_link '" width="80"/></td>';
            
$ads .= '<td align="left" style="border-top:1px solid #ddd"><a href="' osc_item_url_ns($item['pk_i_id']) . '">' $item['s_title'] . '</a><br/><span>' osc_highlight($item['s_description'], 115) . '</span></td>';

            
$ads .= '</tr>';
          }

          
$ads .= '</table>';


          
// Now loop alerts. At least 1 should be there (original $s_search)
          
foreach($alerts as $alert) {
            if(!isset(
$alert['fk_i_user_id']) && !isset($alert['s_email'])) {
              continue;
            }

            
Alerts::newInstance()->increaseTrigger($alert['pk_i_id']);

            
$user = array();
            
            
// Find user record
            
if($alert['fk_i_user_id'] > 0) {
              
$user $mUser->findByPrimaryKey($alert['fk_i_user_id']);
            } else {
              
$user $mUser->findByEmail($alert['s_email']);
            }
            
            
// User not found
            
if($user === false || !isset($user['pk_i_id'])) {
              
$user = array(
                
'pk_i_id'  => 0,
                
's_name'  => $alert['s_email'],
                
's_email' => $alert['s_email']
              );
            }
            
            
// Only trigger alert to non-banned users
            
if(osc_is_email_banned($user['s_email']) !== false) {
              
Log::newInstance()->insertLog(
                
'alerts',
                
'notifyUserBanned',
                
$s_search['fk_i_user_id'],
                
sprintf(__('Alert ID %d for user %s (ID %d) was not sent because the user\'s email is banned.'), $s_search['pk_i_id'], $s_search['s_email'], $s_search['fk_i_user_id']),
                
'cron',
                
0
              
);
              
              continue;
            }

            
// Alert is OK to send and log
            
Log::newInstance()->insertLog(
              
'alerts',
              
'notifyUser',
              
$user['pk_i_id'],
              
sprintf(__('%d listings matched alert ID %d for user %s (ID %d)'), $totalItems$alert['pk_i_id'], $user['s_email'], $user['fk_i_user_id']),
              
'cron',
              
0
            
);

            
// Trigger email
            // hook_alert_email_hourly, hook_alert_email_daily, hook_alert_email_weekly, hook_alert_email_instant
            
osc_run_hook('hook_' $internal_name$user$ads$alert$items$totalItems);
            
AlertsStats::newInstance()->increase(date('Y-m-d'));
          }
        }
      }
    }
  }
}
  To get fast support, we need following details: Detail description, URL to reproduce problem, Screenshots

*

MB Themes

Re: The subscription to the search does not work
« Reply #11 on: January 20, 2026, 10:57:34 AM »
Ok, today I've took more time to review this and decided to rewrite whole alerts.

In order to make it working on Osclass 8.3.1, add this function to oc-includes/osclass/helpers/hUser.php

Code: [Select]
function osc_get_user_row_by_email($email) {
  $email = trim((string)$email);
 
  if($email == '') {
    return false;
  }

  if(View::newInstance()->_exists('user_' . $email)) {
    return View::newInstance()->_get('user_' . $email);
  }
 
  $user = User::newInstance()->findByEmail($email);
  View::newInstance()->_exportVariableToView('user_' . $email, $user);
 
  return $user;
}

Then, replace oc-includes/osclass/alerts.php with following:
Code: [Select]
// FUNCTION THAT DRIVES SENDING OF ALERTS
// Added into cron in cron.php
function osc_runAlert($type = '', $last_exec = null){
  $type = strtoupper(trim((string)$type));
  $hook_name = 'hook_alert_email_' . strtolower($type);
  $items_limit_per_alert = ((defined('MAX_ITEMS_PER_ALERT') && MAX_ITEMS_PER_ALERT > 0) ? (int)MAX_ITEMS_PER_ALERT : 200);

  if(!in_array($type, array('HOURLY', 'DAILY', 'WEEKLY', 'INSTANT'))) {
    return false;
  }

  // Get last execution time of cron - this will be filter on pub date on items
  if($last_exec === null) {
    $cron = Cron::newInstance()->getCronByType($type);
    $last_exec = (is_array($cron) && !empty($cron['d_last_exec']) ? $cron['d_last_exec'] : '0000-00-00 00:00:00');
  }
 
  $last_exec_comment = sprintf(__('Type: %s, Exec: %s'), ucwords(strtolower($type)), $last_exec);


  // Get active subscribed alerts by type - daily, hourly, ...
  $alerts = Alerts::newInstance()->findByType($type, true, false);

  if(is_array($alerts) && count($alerts) > 0) {
    foreach($alerts as $alert) {
      $alert_id = $alert['pk_i_id'];
      $user_invalid = false;
     
      // First identify user and prepare user object for hook
      $user_id = (int)($alert['fk_i_user_id'] > 0 ? $alert['fk_i_user_id'] : 0);
      $user_email = $alert['s_email'];
     
      if($user_id > 0) {
        $user = osc_get_user_row($user_id);
      } else {
        $user = osc_get_user_row_by_email($user_email);
      }
     
      if($user === false || !isset($user['pk_i_id'])) {
        $user_invalid = ($user_id > 0 ? true : $user_invalid);    // User was removed
       
        $user = array(
          'pk_i_id' => 0,
          's_name' => $user_email,
          's_email' => $user_email
        );
       
      } else {
        $user_invalid = (($user['b_active'] == 0 || $user['b_enabled'] == 0) ? true : $user_invalid);    // User is not in well state
        $user_email = ($user['s_email'] ?? $user_email);  // prefer email on user record
      }


      // User that subscribed to alert does not exists, is removed, blocked or inactive
      if($user_invalid) {
        Alert::newInstance()->deactivate($alert_id);
        Log::newInstance()->insertLog('alerts', 'userInvalid', $user_id, sprintf(__('Alert ID %d (%s) for user %s (ID %d) triggered, but was not sent because the user\'s user state is invalid (removed, inactive or blocked). This alert has been deactivated.'), $alert_id, strtolower($type), $user_email, $user_id), 'cron', 0, $last_exec_comment);
        continue;
      }

      // Check if user is not banned
      if(osc_is_email_banned($user_email) !== false) {
        Alert::newInstance()->deactivate($alert_id);
        Log::newInstance()->insertLog('alerts', 'userBanned', $user_id, sprintf(__('Alert ID %d (%s) for user %s (ID %d) triggered, but was not sent because the user\'s email is banned. This alert has been deactivated.'), $alert_id, strtolower($type), $user_email, $user_id), 'cron', 0, $last_exec_comment);
        continue;
      }


      // Collect search conditions (for items) and perform search
      $conditions_param = ($alert['s_param'] ?? null);
      $conditions_json = $alert['s_search'];
      $conditions = json_decode($conditions_json, true) ?: [];

      $mSearch = Search::newInstance();
      $mSearch->setJsonAlert($conditions, $user_email, $user_id);
      $mSearch->addConditions(sprintf('%st_item.dt_pub_date > "%s"', DB_TABLE_PREFIX, $last_exec));
      $mSearch->limit(0, $items_limit_per_alert);   // Avoid excessive email with hundreds of listings
     
      $items = $mSearch->doSearch();
      $items_count = $mSearch->count();
      $items_limitted = ($items_count >= $items_limit_per_alert ? true : false);

      // Check if any listing match search criteria
      if(!is_array($items) || empty($items)) {
        Log::newInstance()->insertLog('alerts', 'notifyUserEmpty', $user_id, sprintf(__('Alert ID %d (%s) for user %s (ID %d) triggered, but was not sent because 0 listings match search criteria.'), $alert_id, strtolower($type), $user_email, $user_id), 'cron', 0, $last_exec_comment, $conditions_param);
        continue;
      }

      Log::newInstance()->insertLog('alerts', 'notifyUser', $user_id, sprintf(__('Alert ID %d (%s) for user %s (ID %d) triggered - %d listings matched criteria (limit: %d).'), $alert_id, strtolower($type), $user_email, $user_id, $items_count, $items_limit_per_alert), 'cron', 0, $last_exec_comment, $conditions_param);

      Alerts::newInstance()->increaseTrigger($alert['pk_i_id']);
      AlertsStats::newInstance()->increase(date('Y-m-d'));

      $items_table = '<table id="alert-items" cellspacing="0" cellpadding="8">';

      foreach($items as $item) {
        $resource = ItemResource::newInstance()->getResource($item['pk_i_id']);

        if(isset($resource['pk_i_id']) && $resource['pk_i_id'] > 0) {
          $path = osc_apply_filter('resource_path', osc_base_url().$resource['s_path']);
          $img_link = osc_apply_filter('resource_thumbnail_url', $path . $resource['pk_i_id'] . '_thumbnail.' . $resource['s_extension']);
        } else {
          $img_link = osc_base_url() . 'oc-includes/osclass/gui/images/no_photo.gif';
        }

        $items_table .= '<tr>';
        $items_table .= '<td width="80" style="border-top:1px solid #ddd"><img src="' . $img_link . '" width="80"/></td>';
        $items_table .= '<td align="left" style="border-top:1px solid #ddd"><a href="' . osc_item_url_ns($item['pk_i_id']) . '">' . $item['s_title'] . '</a><br/><span>' . osc_highlight($item['s_description'], 115) . '</span></td>';
        $items_table .= '</tr>';
      }

      $items_table .= '</table>';


      // Trigger email
      // hook_alert_email_hourly, hook_alert_email_daily, hook_alert_email_weekly, hook_alert_email_instant
      osc_run_hook($hook_name, $user, $items_table, $alert, $items, $items_count);
    }
  }
}


Model has been simplified, it simply goes through items and send mails. I think old one worked, but was overcomplicated.
Logs were improved as well

« Last Edit: January 20, 2026, 11:11:48 AM by MB Themes »
  To get fast support, we need following details: Detail description, URL to reproduce problem, Screenshots

*

aviros

  • ***
  • 49 posts
Re: The subscription to the search does not work
« Reply #12 on: January 20, 2026, 01:05:30 PM »
I did everything as you wrote below. I added a function (code) to the oc-includes/osclass/helpers/hUser.php file. I also added code to the oc-includes/osclass/alerts.php file. Now, the emails are not being sent at all! They are not even showing up in the logs. I am attaching my two files, hUser.php and alerts.php. Could you please take a look at them? I may have done something wrong, even though I followed your instructions!  :-[

*

MB Themes

Re: The subscription to the search does not work
« Reply #13 on: January 20, 2026, 01:38:54 PM »
Enable debug mode and review. I have series of successful tests completed with correct functionality.
  To get fast support, we need following details: Detail description, URL to reproduce problem, Screenshots

*

aviros

  • ***
  • 49 posts
Re: The subscription to the search does not work
« Reply #14 on: January 20, 2026, 01:51:48 PM »
Could you please check the files I sent you? Are there any errors? If so, could you send them back to me with the corrections? Then I can enable the log and double-check