summaryrefslogblamecommitdiffstats
path: root/inc/message.inc.php
blob: 119bb2ba5a03cd9251133ed41eb272f56f8dd3cb (plain) (tree)
1
2
3
4
5
6
7
8
9

     

                        


                                       
                                                   
                                        
 




                                                                         
                                                                     
         
                                                  

         
                                                                       
         
                                                   

         
                                                                    
         
                                                

         
                                                                       
         
                                                   





                                                         
                                                                                  
         


                                                                             

                                                             

                                           

















                                                   
                                                        
                                      
                                          
                                          
                                        

                                               
                  


                                           

         




                                                                            
                                                 
         
                                      

                                       
                       
                                   
                                                




                                                                                       
                                                                      
                                                                                                                                 
                         



















                                                                                                    
                 
                                      

         
           


                                                       
                                                 
         

                                                




                                                                                       










                                                                                              


                                                                     
                                                  



                                                                                                                

                                             

                                                                   
                                                                
                         


                                                                                       






                                                                    
                                                  

                                 
                                                                                      


                                                                    

                                                                                          
                                                                                       





                                            

 
<?php

declare(strict_types=1);

class Message
{
	private static $list = array();
	private static $alreadyDisplayed = array();
	private static $flushed = false;

	/**
	 * Add error message to page. If messages have not been flushed
	 * yet, it will be added to the queue, otherwise it will be added
	 * in place during rendering.
	 */
	public static function addError(string $id, ...$params): void
	{
		self::add('danger', $id, $params);
	}

	public static function addWarning(string $id, ...$params): void
	{
		self::add('warning', $id, $params);
	}

	public static function addInfo(string $id, ...$params): void
	{
		self::add('info', $id, $params);
	}

	public static function addSuccess(string $id, ...$params): void
	{
		self::add('success', $id, $params);
	}

	/**
	 * Internal function that adds a message. Used by
	 * addError/Success/Info/... above.
	 */
	private static function add(string $type, string $id, array $params): void
	{
		if (strstr($id, '.') === false) {
			$id = Page::getModule()->getIdentifier() . '.' . $id;
		}
		if (!empty($params) && $params[0] === true) {
			$params = array_slice($params, 1);
			$linkModule = true;
		} else {
			$linkModule = false;
		}
		switch ($type) {
		case 'danger':
			$icon = 'exclamation-sign';
			break;
		case 'warning':
			$icon = 'warning';
			break;
		case 'info':
			$icon = 'info-sign';
			break;
		case 'success':
			$icon = 'ok';
			break;
		default:
			$icon = '';
		}
		ArrayUtil::forceType($params, 'string');
		self::$list[] = array(
			'type'   => $type,
			'icon'   => $icon,
			'id'     => $id,
			'params' => $params,
			'link'   => $linkModule
		);
		if (self::$flushed) {
			self::renderList();
		}
	}

	/**
	 * Render all currently queued messages, flushing the queue.
	 * After calling this, any further calls to add* will be rendered in
	 * place in the current page output.
	 */
	public static function renderList(): void
	{
		self::$flushed = true;
		if (empty(self::$list))
			return;
		// Ajax
		$mangled = array();
		foreach (self::$list as $item) {
			if (!preg_match('/^(\w+)\.(.+)$/', $item['id'], $out)) {
				$message = 'Invalid Message ID format: ' . $item['id'];
			} else {
				$message = Dictionary::getMessage($out[1], $out[2]);
			}
			foreach ($item['params'] as $index => $text) {
				$message = str_replace('{{' . $index . '}}', '<b>' . htmlspecialchars($text) . '</b>', $message);
			}
			if ($item['link'] && isset($out[1])) {
				$item['link'] = $out[1];
			}
			$mangled[] = array(
				'type' => $item['type'],
				'icon' => $item['icon'],
				'message' => $message,
				'link' => $item['link']
			);
		}
		if (AJAX) {
			foreach ($mangled as $entry) {
				echo Render::parse('messagebox', $entry, 'main');
			}
		} else {
			// Non-Ajax
			foreach ($mangled as $entry) {
				Render::addTemplate('messagebox', $entry, 'main');
			}
			self::$alreadyDisplayed = array_merge(self::$alreadyDisplayed, self::$list);
		}
		self::$list = array();
	}

	/**
	 * Get all queued messages, flushing the queue.
	 * Useful in api/ajax mode.
	 */
	public static function asString(): string
	{
		$return = '';
		foreach (self::$list as $item) {
			if (!preg_match('/^(\w+)\.(.+)$/', $item['id'], $out)) {
				$message = 'Invalid Message ID format: ' . $item['id'];
			} else {
				$message = Dictionary::getMessage($out[1], $out[2]);
			}
			foreach ($item['params'] as $index => $text) {
				$message = str_replace('{{' . $index . '}}', $text, $message);
			}
			$return .= '[' . $item['type'] . ']: ' . $message . "\n";
			self::$alreadyDisplayed[] = $item;
		}
		self::$list = array();
		return $return;
	}

	/**
	 * Deserialize any messages from the current HTTP request and
	 * place them in the message queue.
	 */
	public static function fromRequest(): void
	{
		$messages = is_array($_REQUEST['message']) ? $_REQUEST['message'] : array($_REQUEST['message']);
		foreach ($messages as $message) {
			$data = explode('|', $message);
			if (count($data) < 2)
				continue;
			if (substr($data[0], -1) === '@') {
				$data[0] = substr($data[0], 0, -1);
				array_splice($data, 2, 0, true);
			}
			if (!preg_match('/^(danger|warning|info|success)$/', $data[0]))
				continue;
			self::add($data[0], $data[1], array_slice($data, 2));
		}
	}

	/**
	 * Turn the current message queue into a serialized version,
	 * suitable for appending to a GET or POST request
	 */
	public static function toRequest(): string
	{
		$parts = array();
		foreach (array_merge(self::$list, self::$alreadyDisplayed) as $item) {
			if (isset($item['link']) && $item['link']) {
				$item['type'] .= '@';
			}
			$str = 'message[]=' . urlencode($item['type'] . '|' .$item['id']);
			if (!empty($item['params'])) {
				$str .= '|' . urlencode(implode('|', $item['params']));
			}
			$parts[] = $str;
		}
		return implode('&', $parts);
	}

}