Temporary fixes for php encoding library bugs ending with segfault.
[fa-stable.git] / admin / inst_module.php
1 <?php
2 /**********************************************************************
3     Copyright (C) FrontAccounting, LLC.
4         Released under the terms of the GNU General Public License, GPL, 
5         as published by the Free Software Foundation, either version 3 
6         of the License, or (at your option) any later version.
7     This program is distributed in the hope that it will be useful,
8     but WITHOUT ANY WARRANTY; without even the implied warranty of
9     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
10     See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
11 ***********************************************************************/
12 $page_security = 'SA_CREATEMODULES';
13 $path_to_root="..";
14 include_once($path_to_root . "/includes/session.inc");
15 include_once($path_to_root."/includes/packages.inc");
16
17 if ($SysPrefs->use_popup_windows) {
18         $js = get_js_open_window(900, 500);
19 }
20 page(_($help_context = "Install/Activate extensions"), false, false, "", $js);
21
22 include_once($path_to_root . "/includes/date_functions.inc");
23 include_once($path_to_root . "/admin/db/company_db.inc");
24 include_once($path_to_root . "/admin/db/maintenance_db.inc");
25 include_once($path_to_root . "/includes/ui.inc");
26
27 simple_page_mode(true);
28
29 //---------------------------------------------------------------------------------------------
30 function local_extension($id)
31 {
32         global $next_extension_id, $Ajax, $path_to_root;
33
34         $exts = get_company_extensions();
35         $exts[$next_extension_id++] = array(
36                         'package' => $id,
37                         'name' => $id,
38                         'version' => '-',
39                         'available' => '',
40                         'type' => 'extension',
41                         'path' => 'modules/'.$id,
42                         'active' => false
43         );
44
45         if (file_exists($path_to_root.'/modules/'.clean_file_name($id).'/hooks.php')) {
46                 include_once($path_to_root.'/modules/'.clean_file_name($id).'/hooks.php');
47         }
48         $hooks_class = 'hooks_'.$id;
49         if (class_exists($hooks_class, false)) {
50                 $hooks = new $hooks_class;
51                 $hooks->install_extension(false);
52         }
53         $Ajax->activate('ext_tbl'); // refresh settings display
54         if (!update_extensions($exts))
55                 return false;
56         return true;
57 }
58
59 function handle_delete($id)
60 {
61         global $path_to_root;
62         
63         $extensions = get_company_extensions();
64         $ext = $extensions[$id];
65         if ($ext['version'] != '-') {
66                 if (!uninstall_package($ext['package']))
67                         return false;
68         } else {
69                 @include_once($path_to_root.'/'.$ext['path'].'/hooks.php');
70                 $hooks_class = 'hooks_'.$ext['package'];
71                 if (class_exists($hooks_class)) {
72                         $hooks = new $hooks_class;
73                         $hooks->uninstall_extension(false);
74                 }
75         }
76         unset($extensions[$id]);
77         if (update_extensions($extensions)) {
78                 display_notification(_("Selected extension has been successfully deleted"));
79         }
80         return true;
81 }
82 //
83 // Helper for formating menu tabs/entries to be displayed in extension table
84 //
85 function fmt_titles($defs)
86 {
87                 if (!$defs) return '';
88                 foreach($defs as $def) {
89                         $str[] = access_string($def['title'], true);
90                 }
91                 return implode('<br>', array_values($str));
92 }
93 //---------------------------------------------------------------------------------------------
94 //
95 // Display list of all extensions - installed and available from repository
96 //
97 function display_extensions($mods)
98 {
99         global $installed_extensions;
100         
101         div_start('ext_tbl');
102         start_table(TABLESTYLE);
103
104         $th = array(_("Extension"),_("Modules provided"), _("Options provided"),
105                  _("Installed"), _("Available"),  "", "");
106         table_header($th);
107
108         $k = 0;
109
110         foreach($mods as $pkg_name => $ext)
111         {
112                 $available = @$ext['available'];
113                 $installed = @$ext['version'];
114                 $id = @$ext['local_id'];
115
116                 $entries = fmt_titles(@$ext['entries']);
117                 $tabs = fmt_titles(@$ext['tabs']);
118
119                 alt_table_row_color($k);
120
121                 label_cell($available ? get_package_view_str($pkg_name, $ext['name']) : $ext['name']);
122                 label_cell($tabs);
123                 label_cell($entries);
124
125                 label_cell($id === null ? _("None") :
126                         ($available && $installed ? $installed : _("Unknown")));
127                 label_cell($available ? $available : _("Unknown"));
128
129                 if (!$available && $ext['type'] == 'extension') {// third-party plugin
130                         if (!$installed)
131                                 button_cell('Local'.$ext['package'], _("Install"), _('Install third-party extension.'), 
132                                         ICON_DOWN);
133                         else
134                                 label_cell('');
135                 } elseif (check_pkg_upgrade($installed, $available)) // outdated or not installed extension in repo
136                         button_cell('Update'.$pkg_name, $installed ? _("Update") : _("Install"),
137                                 _('Upload and install latest extension package'), ICON_DOWN);
138                 else
139                         label_cell('');
140
141                 if ($id !== null) {
142                         delete_button_cell('Delete'.$id, _('Delete'));
143                         submit_js_confirm('Delete'.$id, 
144                                 sprintf(_("You are about to remove package \'%s\'.\nDo you want to continue ?"), 
145                                         $ext['name']));
146                 } else
147                         label_cell('');
148
149                 end_row();
150         }
151
152         end_table(1);
153
154         submit_center_first('Refresh', _("Update"), '', null);
155
156         div_end();
157 }
158 //---------------------------------------------------------------------------------
159 //
160 // Get all installed extensions and display
161 // with current status stored in company directory.
162 //
163 function company_extensions($id)
164 {
165         start_table(TABLESTYLE);
166         
167         $th = array(_("Extension"),_("Modules provided"), _("Options provided"), _("Active"));
168         
169         $mods = get_company_extensions();
170         $exts = get_company_extensions($id);
171         foreach($mods as $key => $ins) {
172                 foreach($exts as $ext)
173                         if ($ext['name'] == $ins['name']) {
174                                 $mods[$key]['active'] = @$ext['active'];
175                                 continue 2;
176                         }
177         }
178         $mods = array_natsort($mods, null, 'name');
179         table_header($th);
180         $k = 0;
181         foreach($mods as $i => $mod)
182         {
183                 if ($mod['type'] != 'extension') continue;
184                 alt_table_row_color($k);
185                 label_cell($mod['name']);
186                 $entries = fmt_titles(@$mod['entries']);
187                 $tabs = fmt_titles(@$mod['tabs']);
188                 label_cell($tabs);
189                 label_cell($entries);
190
191                 check_cells(null, 'Active'.$i, @$mod['active'] ? 1:0, 
192                         false, false, "align='center'");
193                 end_row();
194         }
195
196         end_table(1);
197         submit_center('Refresh', _('Update'), true, false, 'default');
198 }
199
200 //---------------------------------------------------------------------------------------------
201 if ($Mode == 'Delete')
202 {
203         handle_delete($selected_id);
204         $Mode = 'RESET';
205 }
206
207 if (get_post('Refresh')) {
208         $comp = get_post('extset');
209         $exts = get_company_extensions($comp);
210
211         $result = true;
212         foreach($exts as $i => $ext) {
213                 if ($ext['package'] && ($ext['active'] ^ check_value('Active'.$i))) 
214                 {
215                         if (check_value('Active'.$i) && !check_src_ext_version($ext['version']))
216                         {
217                                 display_warning(sprintf(_("Package '%s' is incompatible with current application version and cannot be activated.\n")
218                                         . _("Check Install/Activate page for newer package version."), $ext['name']));
219                                 continue;
220                         }
221                         $activated = activate_hooks($ext['package'], $comp, !$ext['active']);   // change active state
222
223                         if ($activated !== null)
224                                 $result &= $activated;
225                         if ($activated || ($activated === null))
226                                 $exts[$i]['active'] = check_value('Active'.$i);
227                 }
228         }
229         write_extensions($exts, get_post('extset'));
230         if (get_post('extset') == user_company())
231                 $installed_extensions = $exts;
232         
233         if(!$result) {
234                 display_error(_('Status change for some extensions failed.'));
235                 $Ajax->activate('ext_tbl'); // refresh settings display
236         }else
237                 display_notification(_('Current active extensions set has been saved.'));
238 }
239
240 if ($id = find_submit('Update', false))
241         install_extension($id);
242
243 if ($id = find_submit('Local', false))
244         local_extension($id);
245
246 if ($Mode == 'RESET')
247 {
248         $selected_id = -1;
249         unset($_POST);
250 }
251
252 //---------------------------------------------------------------------------------------------
253 start_form(true);
254 if (list_updated('extset'))
255         $Ajax->activate('_page_body');
256
257 $set = get_post('extset', -1);
258
259 echo "<center>" . _('Extensions:') . "&nbsp;&nbsp;";
260 echo extset_list('extset', null, true);
261 echo "</center><br>";
262
263 if ($set == -1) 
264 {
265         $mods = get_extensions_list('extension');
266         if (!$mods)
267                 display_note(_("No optional extension module is currently available."));
268         else
269                 display_extensions($mods);
270 } else 
271         company_extensions($set);
272
273 //---------------------------------------------------------------------------------------------
274 end_form();
275
276 end_page();