Location: PHPKode > projects > Streber > std/mail.inc.php
<?php if(!function_exists('startedIndexPhp')) { header("location:../index.php"); exit();}
# streber - a php5 based project management system  (c) 2005-2007  / www.streber-pm.org
# Distributed under the terms and conditions of the GPL as stated in lang/license.html


require_once(confGet('DIR_STREBER') . './db/class_task.inc.php');
require_once(confGet('DIR_STREBER') . './db/class_project.inc.php');
require_once(confGet('DIR_STREBER') . './db/class_person.inc.php');
require_once(confGet('DIR_STREBER') . './db/db_item.inc.php');
require_once(confGet('DIR_STREBER') . './db/db_itemperson.inc.php');
//require_once(confGet('DIR_STREBER') . 'render/render_misc.inc.php');


class Notifier
{

    /**
    * go through all accounts and collect information
    *
    * returns array of count of... [$num_notification_sent, $num_warnings]
    */
    public function sendNotifications()
    {
        global $PH;
        $persons=Person::getPersons(array('visible_only'=>false, 'can_login'=>true));

        $num_notifications_sent = 0;
        $num_warnings = 0;
        foreach($persons as $p) {
            if($p->settings & USER_SETTING_NOTIFICATIONS) {
                if($p->office_email  || $p->personal_email )  {
                    $now= time();
                    $last= strToGMTime($p->notification_last);
                    $period= $p->notification_period * 60*60*24;

                    if(strToGMTime($p->notification_last) + $period  < time() || $period == -1) {
                        $result= $this->sendNotifcationForPerson($p);
                        if($result) {
                            ### reset activation-flag ###
                            $p->settings &= USER_SETTING_SEND_ACTIVATION ^ RIGHT_ALL;
                            $p->notification_last= gmdate("Y-m-d H:i:s");
                            $p->update();
                            if($result === true) {
                                $num_notifications_sent++;
                            }
                            else {
                                $num_warnings++;
                                new FeedbackWarning(sprintf(__('Failure sending mail: %s'), $result));
                            }
                        }
                    }
                }
            }
        }
        return array($num_notifications_sent, $num_warnings);
    }



    /**
    * returns:
    *   number of changes since notification_last
    *   0 - if nothing happend and no mail has been send
    *
    * person->last_notification is NOT been updated
    *
    * NOTE some tips used from Jon Webb [Madrid&London]
    *                          http://www.php.net/manual/en/ref.mail.php#61644
    *
    */
    public function sendNotifcationForPerson($person)
    {
        $information_count = 0;
        $from_domain = confGet('SELF_DOMAIN');
        $url= confGet('SELF_PROTOCOL').'://'.confGet('SELF_URL');
		
        /**
        * remove script name if clean urls.
        */
        if(confGet('USE_MOD_REWRITE')) {
            $url= str_replace('index.php','',$url);
        }

        /**
        * temporary overwrite the current-user to obey item-visibility
        * MUST BE RESET BEFORE LEAVING THIS FUNCTION!
        */
        global $auth;
        $keep_cur_user= $auth->cur_user;
        $auth->cur_user= $person;

        setLang($person->language);


        ### from-address  ###
        $from = __('Streber Email Notification','notifcation mail from') . " <do-not-reply@".$from_domain.">";

		### reply-addres? ###
		$reply="do-not-reply@$from_domain";

        if($person->office_email) {
            $to= $person->office_email;
        }
        else if($person->personal_email) {
            $to= $person->personal_email;
        }
        else {
            if(isset($auth->cur_user->language)) {
                setLang($auth->cur_user->language);
            }
            $auh->cur_user = $keep_cur_user;
            return _('no mail for person','notification');
        }

		### subject ###
		$subject = sprintf(__('Updates at %s','notification mail subject'), confGet('SELF_DOMAIN'));
		
		### message ###
        $message_txt= '';
        $message_html= '';

		$message_html.= "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n\r<html>\r\n"
                . "<head>\n\r"
                . "<meta content=\"text/html;charset=UTF-8\" http-equiv=\"Content-Type\">\n\r"
                . "<title>$subject</title>\n\r"
                . "<style>\n\r\n\r\n\r h4 {font-size:11pt;}\n\r li{ margin-bottom:0.2em; } ul {margin:0; padding:0px 0px 0px 1em;}li span.details { font-size: 10pt; color: #888}\n\r</style>\n\r"
                . "</head>\n\r"
                . "<body text=\"#000000\" link=\"#163075\" alink=\"#ff0000\" vlink=\"#2046AA\">\n\r"
                . sprintf(__('Hello %s,','notification'), asHtml($person->name))
                . "<br><br>\n\r"
                . __('with this automatically created e-mail we want to inform you that', 'notification')
                . "<br>\n\r";
        $message_txt.= sprintf(__('Hello %s,','notification'), $person->name)
                    . "\n\r"
                    . __('with this automatically created e-mail we want to inform you that', 'notification')
                    . "\n\r";

        if($person->notification_last) {
            $message_html.= sprintf(__('since %s'), renderDate($person->notification_last, false) ). ' ';
            $message_txt.= sprintf(__('since %s'), renderDate($person->notification_last, false) ). ' ';
        }

        $message_html.= sprintf(__('following happened at %s ','notification'),
                         "<a href='" . $url ."'>" . confGet('SELF_DOMAIN')."</a>"
                   )
                . "<br>\n\r";
        $message_txt.= sprintf(__('following happened at %s ','notification'),confGet('SELF_DOMAIN'))
                    ."\n\r";

        ### new account ###
        if($person->settings & USER_SETTING_SEND_ACTIVATION) {
            $message_html.= __('Your account has been created.','notification')
                    . "<a href='$url?go=activateAccount&tuid={$person->identifier}'>"
                    . __('Please set a password to activate it.','notification')
                    . "</a><br>\n\r";

            $message_txt.= __('Your account has been created.','notification')
                    . " "
                    . __('Please set a password to activate it.','notification')
                    . "\n\r "
                    . $url."?go=activateAccount&tuid={$person->identifier}"
                    . "\n\r\n\r";

            $information_count++;
        }
		
        ### recently assigned to projects ###
        $projects= array();
        {
            $headline_html= "<h3>\n\r"
                     . __('You have been assigned to projects:','notification')
                     . "</h3>\n\r"
                     . "<ul>\n\r";
            $headline_txt= "\n\r". __('You have been assigned to projects:','notification')."\n\r";

            $close_list_html= '';
            $close_list_txt= '';


            $pps= $person->getProjectPersons();
            foreach($pps as $pp) {
                if($project= Project::getVisibleById($pp->project)) {
                    if($project->state) {
                        $projects[]= $project;
                        if(strToGMTime($pp->created) > strToGMTime($person->notification_last)) {
                            $message_html.= $headline_html;
                            $message_txt.= $headline_txt;
                            $message_html.="<li>";
                            if(confGet('USE_MOD_REWRITE')) {
                                $message_html.= "<a href='$url{$pp->project}'>". asHtml($project->name) ."</a>";
                            }
                            else {
                                $message_html.= "<a href='$url?go=projView&prj={$pp->project}'>". asHtml($project->name) ."</a>";
                            }
                            $message_html. "</li>\n\r";
                            $message_txt.= "- ". $project->name. "\n\r";

                            $headline_html='';
                            $headline_txt='';
                            $close_list_html= "</ul>\n\r";
                            $close_list_txt= "\n\r";
                            $information_count++;
                        }
                    }
                }
            }
            $message_html.= $close_list_html;
            $message_txt.= $close_list_txt;
        }
		
		### changed and unchanged items ###
		{
			## All changed items ##
		 	$changes_headline_html = '';
        	$changes_headline_txt = '';
			$changes_message_html = '';
        	$changes_message_txt = '';
			
			$monitored_items = ItemPerson::getAll(array(
			                   'is_bookmark'=>1,
							   'notify_on_change'=>1,
							   'person'=>$person->id));
							   
			if($monitored_items){
				$changes_headline_html = "<h3>"
                     . __('Changed monitored items:','notification')
                     . "</h3>"
                     . "<ul>";
            	$changes_headline_txt = "\n\r". __('Changed monitored items:','notification')."\n\r";
								
				foreach($monitored_items as $mi){
					if($pi = DbProjectItem::getById($mi->item)){
						if(strToGMTime($pi->modified) > strToGMTime($person->notification_last)){
							if($pi->modified_by != $auth->cur_user->id){
								$information_count++;
								$p = Person::GetVisibleById($pi->modified_by);
								$object = DbProjectItem::getObjectById($pi->id);
								$changes_message_html .= '<li>' . sprintf(__("%s edited > %s"), $p->nickname, $object->name) . '</li>';
								$changes_message_txt .= '- ' . sprintf(__("%s edited > %s"), $p->nickname, $object->name) . '\n\r';
							}
						}
					}
				}
				if($changes_message_html != ''){
					$changes_message_html .= "</ul>";
					$changes_message_txt .= "\n\r";
				}
			}
			
			## All unchanged items ##
			$unchanged_headline_html = '';
        	$unchanged_headline_txt = '';
			$unchanged_message_html = '';
        	$unchanged_message_txt = '';
			
			$monitored_items_unchanged = ItemPerson::getAll(array(
			                           'is_bookmark'=>1,
							           'notify_if_unchanged_min'=>NOTIFY_1DAY,
							           'person'=>$person->id));
							   
			if($monitored_items_unchanged){
				
				$unchanged_headline_html = "<h3>"
                     . __('Unchanged monitored items:','notification')
                     . "</h3>" 
                     . "<ul>";
            	$unchanged_headline_txt = "\n\r". __('Unchanged monitored items:','notification')."\n\r";
												
				foreach($monitored_items_unchanged as $miu){
					## reminder period ##
					$period = '';
					switch($miu->notify_if_unchanged){
						case NOTIFY_1DAY:
							$period = 24*60*60;
							break;
						case NOTIFY_2DAYS:
							$period = 2*24*60*60;
							break;
						case NOTIFY_3DAYS:
							$period = 3*24*60*60;
							break;
						case NOTIFY_4DAYS:
							$period = 4*24*60*60;
							break;
						case NOTIFY_5DAYS:
							$period = 5*24*60*60;
							break;
						case NOTIFY_1WEEK:
							$period = 7*24*60*60;
							break;
						case NOTIFY_2WEEKS:
							$period = 2*7*24*60*60;
							break;
						case NOTIFY_3WEEKS:
							$period = 3*7*24*60*60;
							break;
						case NOTIFY_1MONTH:
							$period = 4*7*24*60*60;
							break;
						case NOTIFY_2MONTH:
							$period = 2*4*7*24*60*60;
							break;
					}
					
					$date = $miu->notify_date;
					
					if($pi = DbProjectItem::getVisibleById($miu->item)){
						#if(strToGMTime($pi->modified) > strToGMTime($person->notification_last)){
							$mod_date = $pi->modified;
							if($date != '0000-00-00 00:00:00'){
								$date = strToGMTime($date) + $period;
								$date = date('Y-m-d H:i:s',$date);
								if(($date >= $mod_date) && (strToGMTime($date) <= time())){
									$diff = strToGMTime($date) - strToGMTime($mod_date);
									if($diff >= $period){
										### diff in days ###
										$information_count++;
										$days = round((time() - strToGMTime($miu->notify_date)) / 60 / 60 / 24);
										$object = DbProjectItem::getObjectById($pi->id);
										
										$unchanged_message_html .= '<li>' . sprintf(__("%s (not touched since %s day(s))"), asHtml($object->name), $days) . '</li>';
										$unchanged_message_txt .= '- ' . sprintf(__("%s (not touched since %s day(s))"), $object->name, $days) . '\n\r';
									}
								}
							}
						#}
					}
				}
				if($unchanged_message_html != ''){
					$unchanged_message_html .= "</ul>";
					$unchanged_message_txt .= "\n\r";
				}
			}
		}
		if($changes_message_html != ''){
			$message_html .= $changes_headline_html . $changes_message_html;
			$message_txt .= $changes_headline_txt . $changes_message_txt;
		}
		if($unchanged_message_html != ''){
			$message_html .= $unchanged_headline_html . $unchanged_message_html;
			$message_txt .= $unchanged_headline_txt . $unchanged_message_txt;
		}
		
        ### list project changes ###
        require_once(confGet('DIR_STREBER') . './lists/list_changes.inc.php');

        $updates_html='';
        $updates_txt='';

        foreach($projects as $p) {
            if($changes= ChangeLine::getChangeLinesForPerson($person,$p, $person->notification_last)) {
                $information_count++;
                $updates_html.= "<h4>\n\r";
                if(confGet('USE_MOD_REWRITE')) {
                    $updates_html.="<a href='$url{$p->id}'>". asHtml($p->name) ."</a>";
                }
                else {
                    $updates_html.="<a href='$url?go=projView&amp;prj={$p->id}'>". asHtml($p->name) ."</a>";
                }


                $updates_html.= "</h4>\n\r<ul>\n\r";
                $updates_txt.= "\n\r". $p->name."\n\r";

                foreach($changes as $c) {
                    $updates_html.="<li>";
                    $updates_txt.="\n\r- ";

                    ### task
                    if($c->item && $c->item->type == ITEM_TASK) {
                        $task= $c->item;
                        //@TODO is to expensive to call this function in a for each loop. I suggest a local variable at mail.inc.php#line76
                        if(confGet('USE_MOD_REWRITE')) {
                		  $updates_html.= "<a href='$url{$task->id}'>". asHtml($task->name). "</a>";
                		}
                		else {
                		  $updates_html.= "<a href='$url?go=taskView&amp;tsk={$task->id}'>". asHtml($task->name). "</a>";
                		}
                        $updates_txt.= $task->name;
                    }
                    else if ($c->item && $c->item->type == ITEM_FILE) {
                        $file= $c->item;
                        if(confGet('USE_MOD_REWRITE')) {
                		  $updates_html.= "<a href='$url{$file->id}'>". asHtml($file->name). "</a>";
                		}
                		else {
                		  $updates_html.= "<a href='$url?go=fileView&amp;tsk={$file->id}'>". asHtml($file->name). "</a>";
                		}
                        $updates_txt.= $file->name;                        
                    }

                    $updates_html.= '<br><span class="details">';		# invisible user
                    $updates_txt.= "\n\r";		# invisible user
                    
                    ### what...
                    if($c->html_what) {
                        $updates_html.= $c->html_what. ' ';
                        $updates_txt.= isset($c->txt_what)
                                    ? $c->txt_what
                                    : strip_tags($c->html_what);
                    }

                    $updates_html.= ' ' . __("by") . ' ';		# invisible user
                    $updates_txt .= ' ' . __("by") . ' ';		# invisible user

                    ### who...
                    if($c->person_by) {
                        if($p_who= Person::getVisibleById($c->person_by)) {
                    		$updates_html.= "<b>". asHtml($p_who->nickname) ."</b>"
                    		      ." ";
                    		$updates_txt.= $p_who->nickname
                    		      .": ";

                        }
                        else {
                        	$updates_html.= '??? ';		# invisible user
                        	$updates_txt .= '???: ';		# invisible user
                        }
                    }

                    ### when...
                    if($c->timestamp) {
                        $updates_html.=  ' - ' . renderTimestamp($c->timestamp);
                        $updates_txt .=  ' - ' . renderTimestamp($c->timestamp);
                    }

                    ### to...
                    /**
                    * @@@ bug: this contains internal links that can be viewed from mail
                    **/
                    if($c->html_assignment) {
                        $updates_html.= ' ('.$c->html_assignment. ') ';
                        #$updates_txt.= ' '.$c->html_assignment. ' ';
                    }
                    $updates_html.="</span></li>\n\r";
                    $updates_txt.="\n\r";
                }
                $updates_html.="</ul>\n\r";
                $updates_txt.="\n\r";
            }
        }
        if($updates_html) {
            $message_html.="<h3>". __('Project Updates'). "</h3>\n\r"
                    . $updates_html;
            $message_txt.= "\n\r== ". __('Project Updates'). " ==\n\r"
                    . $updates_txt;

        }

        ### footer ####
        {
            $message_html.=
              "<br><span class=\"details\">\n\r"
              .__('Forgot your password or how to log in?','notification'). '<br>'
              . "<a href='$url?go=loginForgotPasswordSubmit&amp;login_name={$person->nickname}'>"
              . __('Request a mail to change your account settings.','notification')
              . "</a></span>"
              . "."
              . "<br>\n\r"
              . "<br>\n\r"
              .__('Thanks for your time','notification') . "<br>\n\r"
              .__('the management', 'notification') . "\n\r";

            $message_txt.= ''
              .__('Forgot your password or how to log in?','notification'). ' '
              .__("Click here:") . ' ' . "$url?go=loginForgotPasswordSubmit&amp;login_name={$person->nickname}"
              . "\n\r"
              . "\n\r"
              .'  ' . __('Thanks for your time','notification') . "\n\r"
              .'  ' . __('the management', 'notification');

        }

        $message_html.="</body>\n\r"
                . "</html>";


        if($smtp= confGet('SMTP')) {
            ini_set('SMTP', $smtp);
        }
        if($information_count) {


            /**
            *
            * using some t
            */
            if (strtoupper(substr(PHP_OS,0,3)=='WIN')) {
              $eol="\n\r";
            }
            elseif (strtoupper(substr(PHP_OS,0,3)=='MAC')) {
              $eol="\n\r";
            }
            else {
              $eol="\n\r";
            }


            $boundary= "-streber--------------------------------------";
    		### headers  ###
    		#$headers = "Return-Path: <$reply>\r\n";
    		$headers="";
		    #$headers .= "Content-Type: text/html; charset=UTF-8\r\n"
            #$headers .= "Content-Type: multipart/related; boundary=\"".$boundary."\"".$eol;
            $headers .= "Content-Type: multipart/alternative; boundary=\"".$boundary."\"".$eol;
		    #$headers .= "Content-type: multipart/alternative;". $eol
            #         .  " boundary=\"$boundary\"". $eol;
            $headers .= "From: $from". $eol;
            $headers .= 'MIME-Version: 1.0'.$eol;

            $msg     = "Content-Type: multipart/alternative".$eol;
            $msg    .= "This is a multipart message".$eol
                    . "--".$boundary. $eol
                    . "Content-Type: text/plain; charset=UTF-8". $eol. $eol
                    . $message_txt
                    . $eol
                    . "--".$boundary.$eol
                    . "Content-Type: text/html; charset=UTF-8". $eol
                    . $eol
                    . $message_html
                    . $eol
                    . "--".$boundary."--". $eol.$eol
                    ;


    		### just do it ###
    		/**
    		* NOTE: capturing error-output of mail is done in errorhandler.inc,
    		* it sets the global variable $g_error_mail
    		*/

            if(isset($auth->cur_user->language)) {
                setLang($auth->cur_user->language);
            }

            mail($to, $subject, $msg, $headers);
			
            global $g_error_mail;
            if(isset($g_error_mail)) {
                $error= $g_error_mail. ' ("'. $to. '" <'. $person->name .'>)';
                $error=asHtml($error);
                $g_error_mail=NULL;
                $auth->cur_user= $keep_cur_user;
                return $error;
            }
            else {
                $auth->cur_user= $keep_cur_user;
                return true;
            }
    	}
    	else {
    	   new FeedbackMessage(sprintf(__('No news for <b>%s</b>'), $person->name));
            if(isset($auth->cur_user->language)) {
                setLang($auth->cur_user->language);
            }
    	}
        $auth->cur_user= $keep_cur_user;
        return NULL;
    }


    /**
    * returns:
    *   number of changes since notification_last
    *   0 - if nothing happend and no mail has been send
    */
    public function sendPasswordReminder($person)
    {
        $url= confGet('SELF_PROTOCOL').'://'.confGet('SELF_URL');
        $from_domain = confGet('SELF_DOMAIN');;

        /**
        * temporary overwrite the current-user to obey item-visibility
        * MUST BE RESET BEFORE LEAVING THIS FUNCTION!
        */
        global $auth;
        $keep_cur_user= $auth->cur_user;
        $auth->cur_user= $person;

        setLang($person->language);

        ### from-address  ###
        //@TODO this must display APP_NAME title.
        $from = __('Streber Email Notification','notifcation mail from') . " <do-not-reply@".$from_domain.">";

        ### reply-addres? ###
        $reply="do-not-reply@$from_domain";

        $to ="";
        if($person->office_email) {
            $to= $person->office_email;
        }
        else if($person->personal_email) {
            $to= $person->personal_email;
        }
        else {
            if(isset($auth->cur_user->language)) {
                setLang($auth->cur_user->language);
            }
            $auh->cur_user = $keep_cur_user;
            return _('no mail for person','notification');
        }

        ### subject ###
        $subject = __('Your account at','notification') . " " . $from_domain;

        ### message ###
        $message= "";

        $html_format = true;
        if($html_format) {
            $message = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n\r"
            ."<html>\n\r"
            ."<head>\n\r"
            ."<title>$subject</title>\n\r"
            . "</head>\n\r"
            ."<body text=\"#000000\" link=\"#163075\" alink=\"#ff0000\" vlink=\"#2046AA\">\n\r"
            . sprintf(__('Hello %s,','notification'), asHtml($person->name)) . "<br><br>\n\r";

            ### new account ###
            $message.= sprintf(__('Your account at %s is still active.','notification'), "<a href='" . $url ."'>" . confGet('SELF_DOMAIN')."</a>") . "<br>\n\r"
            .__('Your login name is','notification') . " '" . $person->nickname . "'<br>\n\r"
            . __('Please use this link to') 
            .' ' 
            . "<a href=\"" . $url . "?go=activateAccount&tuid=" . $person->identifier . "\">"
            . __('update your account settings')
            . "</a>...<br>\n\r";

            ### footer ####
            {
                $message.= "<br>\n\r"
                ."<br>\n\r"
                .__('Thanks for your time','notification') . "<br>\n\r"
                .__('the management', 'notification') . "\n\r";
            }

            $message.="\n\r"
            ."</body>\n\r"
            ."</html>";
        }

        ### headers  ###
        $headers="";
        if($html_format) {
            $headers .= "From: $from\n\r";
            $headers .= "Content-type: text/html; charset=UTF-8\n\r";
        }


        ### just do it ###
        mail($to, $subject, $message, $headers);

        global $g_error_mail;
        if(isset($g_error_mail))         {
            trigger_error($g_error_mail, E_USER_WARNING);
            $auth->cur_user= $keep_cur_user;
            return $g_error_mail;
        }
        $auth->cur_user= $keep_cur_user;
    }
 
}

?>
Return current item: Streber