@@ -42,17 +42,17 @@ public function run($args = [])
4242 self ::$ COMPOSE_ID = rcube_utils::get_input_string ('_id ' , rcube_utils::INPUT_GET );
4343 self ::$ COMPOSE = null ;
4444
45- if (self ::$ COMPOSE_ID && !empty ($ _SESSION [ ' compose_data_ ' . self ::$ COMPOSE_ID ] )) {
46- self ::$ COMPOSE = & $ _SESSION [ ' compose_data_ ' . self ::$ COMPOSE_ID ] ;
45+ if (self ::$ COMPOSE_ID && !empty (self ::get_compose_data ( self :: $ COMPOSE_ID ) )) {
46+ self ::$ COMPOSE = self ::get_compose_data ( self :: $ COMPOSE_ID ) ;
4747 }
4848
4949 // give replicated session storage some time to synchronize
5050 $ retries = 0 ;
5151 while (self ::$ COMPOSE_ID && !is_array (self ::$ COMPOSE ) && $ rcmail ->db ->is_replicated () && $ retries ++ < 5 ) {
5252 usleep (500000 );
5353 $ rcmail ->session ->reload ();
54- if ($ _SESSION [ ' compose_data_ ' . self ::$ COMPOSE_ID ] ) {
55- self ::$ COMPOSE = & $ _SESSION [ ' compose_data_ ' . self ::$ COMPOSE_ID ] ;
54+ if (self ::get_compose_data ( self :: $ COMPOSE_ID ) ) {
55+ self ::$ COMPOSE = self ::get_compose_data ( self :: $ COMPOSE_ID ) ;
5656 }
5757 }
5858
@@ -74,15 +74,14 @@ public function run($args = [])
7474 self ::$ COMPOSE_ID = uniqid (mt_rand ());
7575 $ params = rcube_utils::request2param (rcube_utils::INPUT_GET , 'task|action ' , true );
7676
77- $ _SESSION [ ' compose_data_ ' . self ::$ COMPOSE_ID ] = [
78- 'id ' => self ::$ COMPOSE_ID ,
79- 'param ' => $ params ,
77+ self ::$ COMPOSE = [
78+ 'id ' => self ::$ COMPOSE_ID ,
79+ 'param ' => $ params ,
8080 'mailbox ' => isset ($ params ['mbox ' ]) && strlen ($ params ['mbox ' ])
8181 ? $ params ['mbox ' ] : $ rcmail ->storage ->get_folder (),
8282 ];
83-
84- self ::$ COMPOSE = &$ _SESSION ['compose_data_ ' . self ::$ COMPOSE_ID ];
8583 self ::process_compose_params (self ::$ COMPOSE );
84+ self ::set_compose_data (self ::$ COMPOSE_ID , self ::$ COMPOSE );
8685
8786 // check if folder for saving sent messages exists and is subscribed (#1486802)
8887 if (!empty (self ::$ COMPOSE ['param ' ]['sent_mbox ' ])) {
@@ -336,6 +335,8 @@ public function run($args = [])
336335
337336 self ::spellchecker_init ();
338337
338+ self ::set_compose_data (self ::$ COMPOSE_ID , self ::$ COMPOSE );
339+
339340 $ rcmail ->output ->send ('compose ' );
340341 }
341342
@@ -1730,4 +1731,121 @@ public static function quote_text($text)
17301731
17311732 return rtrim ($ out , "\n" );
17321733 }
1734+
1735+ /**
1736+ * Handles storage actions (get, set, remove) for compose data using the configured backend.
1737+ *
1738+ * @param string $id The compose data identifier
1739+ * @param int $type The action type: 0 = get, 1 = set, 2 = remove
1740+ * @param mixed $data Optional data to store (used for set)
1741+ * @return mixed|null The compose data for get, or null for set/remove
1742+ * @throws Exception If an invalid storage type or action is provided
1743+ */
1744+ private static function _compose_storage_action ($ id , $ type , $ data = null ) {
1745+ $ compose_data = null ;
1746+ $ rcmail = rcmail::get_instance ();
1747+ $ storage_type = $ rcmail ->config ->get ('compose_data_storage ' , 'session ' );
1748+
1749+ switch ($ storage_type ) {
1750+ case 'session ' :
1751+ $ key = "compose_data_ $ id " ;
1752+ switch ($ type ) {
1753+ case 0 :
1754+ $ compose_data = $ _SESSION [$ key ];
1755+ break ;
1756+
1757+ case 1 :
1758+ $ _SESSION [$ key ] = $ data ;
1759+ break ;
1760+
1761+ case 2 :
1762+ $ rcmail ->session ->remove ($ key );
1763+ break ;
1764+
1765+ default :
1766+ throw new Exception ("Invalide storage type " );
1767+
1768+ }
1769+ break ;
1770+
1771+ case 'apc ' :
1772+ case 'db ' :
1773+ case 'redis ' :
1774+ case 'memcache ' :
1775+ $ ttl = $ rcmail ->config ->get ('compose_data_ttl ' , '8h ' );
1776+ $ compose_data = call_user_func ([$ rcmail ->get_cache ('compose_data ' , $ storage_type , $ ttl ), self ::_get_cache_function ($ type )], $ id , $ data ); //$id instead of $key for avoid redundant name in cache
1777+ break ;
1778+
1779+ default :
1780+ $ plugin = $ rcmail ->plugins ->exec_hook (self ::_get_cache_function ($ type ).'_compose_data ' , ['id ' => $ id , 'storage_type ' => $ storage_type , 'data ' => $ data , 'compose_data ' => null ]);
1781+ if (isset ($ plugin ['compose_data ' ])) $ compose_data = $ plugin ['compose_data ' ];
1782+ break ;
1783+ }
1784+
1785+ return $ compose_data ;
1786+ }
1787+
1788+ /**
1789+ * Returns the cache function name corresponding to the action type.
1790+ *
1791+ * @param int $type The action type: 0 = get, 1 = set, 2 = remove
1792+ * @return string The cache function name ('get', 'set', or 'remove')
1793+ * @throws Exception If an invalid action type is provided
1794+ */
1795+ private static function _get_cache_function ($ type ) : string {
1796+ $ cache_function = null ;
1797+ switch ($ type ) {
1798+ case 0 :
1799+ $ cache_function = 'get ' ;
1800+ break ;
1801+
1802+ case 1 :
1803+ $ cache_function = 'set ' ;
1804+ break ;
1805+
1806+ case 2 :
1807+ $ cache_function = 'remove ' ;
1808+ break ;
1809+
1810+ default :
1811+ throw new Exception ("Invalide storage type " );
1812+
1813+ }
1814+
1815+ return $ cache_function ;
1816+ }
1817+
1818+ /**
1819+ * Retrieve compose data by ID from the configured storage backend.
1820+ *
1821+ * @param string $id The compose data identifier
1822+ * @return mixed The compose data if found, or null otherwise
1823+ */
1824+ public static function get_compose_data ($ id ) {
1825+ return self ::_compose_storage_action ($ id , 0 );
1826+ }
1827+
1828+ /**
1829+ * Store compose data by ID in the configured storage backend.
1830+ *
1831+ * @param string $id The compose data identifier
1832+ * @param mixed $data The compose data to store
1833+ * @return mixed The stored compose data
1834+ */
1835+ public static function set_compose_data ($ id , $ data ) {
1836+ self ::_compose_storage_action ($ id , 1 , $ data );
1837+
1838+ return $ data ;
1839+ }
1840+
1841+ /**
1842+ * Remove compose data by ID from the configured storage backend.
1843+ *
1844+ * @param string $id The compose data identifier
1845+ * @return void
1846+ */
1847+ public static function remove_compose_data ($ id ) : void {
1848+ self ::_compose_storage_action ($ id , 2 );
1849+ }
1850+
17331851}
0 commit comments