NOTES FOR SCHOOLMNG PROGRAM BY Metehan 1. Putting some information on the top of the listview: For keiri, we needed to put the totals of the list values. We have to calculate this total values after the template is initialized for the ListView. Therefore, 'processListViewTwo' function is updated for this purpose. Updated files: i. include/ListView/ListView.php -> in function 'processListViewTwo', special processing is added to for module 'Keiri' => total values are calculated (calculating function is within the 'ListHandler_Keiri' class in the /modules/Keiri/include/ListViewClass.php ii. /modules/Keiri/include/ListViewClass.php -> 'SetTotalValues' function is added which calculates the total values and sets the proper template variables. iii. 2. Hiding some tabs from the top module list: Hiding them is easy: just include them within the $app_list_strings['invisible_modules'] array in the include/language/en_us.lang.php and $modInvisList array in the include/modules.php. However, in this way subpanels are also become hidden!!! Temporarily, the function get_available_tabs function and get_available_tab_label function in include/SubPanel/SubPanelDefinitions.php are updated: line 330: || in_array($values_array['module'], $app_list_strings['invisible_modules']) line 366: or in_array($values_array['module'], $app_list_strings['invisible_modules']) If the module is in $app_list_strings['invisible_modules'], its subpanel is shown, however we should check the user's permission in detail. ==> TO BE DONE 3. Subpanel are not getting their titles from 'title_key' but from the ordinary 'key' ==> TO BE FIXED ===> OK FIXED 4. Adding a custom subpanel (defined using ListView functions) Example: Adding the 'teacher' subpanel under the 'Course' detailview. i. update modules/Course/layout_def.php => Add subpanel definition for the 'teacher' ii. update modules/Course/vardefs.php => add the link relation iii. create modules/Course/EditViewTeacherRelation.html if the relation is editable iv. Create the php and html files for the listview in the Teacher module, i.e. modules/Teacher/SubpanelListView.php modules/Teacher/SubpanelListView.html v. update funtion 'HookCustomEditRelationship' in modules/Course/Course.php if you need to handle some variables specially while dispalying vi. create modules/Course/include/ListViewClass.php for handling the special cases for the subpanel listview vii. 5. Name of the commission company for a student is shown hardcoded => take the name properly from the accounts table 6. Permissions etc. How to handle permissions using the ACL modules: 1. Insert the new modules' records into the acl_actions table; in this way modules' actions will be displayed in the role and user settings 2. Add the "function bean_implements" to be able to use the ACL settings 3. Update the permissions duely using the roles from the Admin menu 4. If a special handling is needed using the permissions, add it into the code. Examples: in 'include/SubPanel/SubPanelDefinitions.php' we would like to show subpanels of the modules to which user has 'list' access code at line 333: or (ACLController::moduleSupportsACL($values_array['module']) && ACLController::checkAccess($values_array['module'],'list', true) ) 5. If a subpanel top button is given (select, create etc.) decide to show it according to the permissions to 'edit' view not the 'list' view e.g. include/generic/SugarWidgets/SugarWidgetSubPanelTopSelectButton.php => code on line 64 6. Permission for the Calendar module is given if the user has access one of the event modules, i.e. 'Calls', 'Meetings', 'Tasks'. I have added 'EventInstance' in order to make Calendar visable to Student users. modules/ACL/ACLController.php => code at line 36 7. Give permission to a user for editing a Course-Teacher relation if the user has edit permissions to the Teacher module module/Contacts/Contact.php => code at line 523 8. Make the links to 'teacher' list of a course off. modules/Teacher/SubPanelListView.html => code at line 17 use '{TAG.MAIN}' instead of 'a' 9. Similar to the above item, make the 'edit relation' buttons inactive modules/Teacher/SubPanelListView.html => code at line 21 & 23 use '{TAG.MAIN}' instead of 'a' 10. Get the title of the subpanel properly include/SubPanel/SubPanelDefinitions.php => check if the user has access to listview of the subpanel's module NOTE: at line 369 => or in_array($values_array['module'], $app_list_strings['invisible_modules']) ==> we may revise this since a user may not has access to a invisible module (the new condition above will work for it but we may add new records to 'acl_action' table in the DB. 11. We should change the subpanel of SMSDocuments for Courses into custom subpanels for permissions: Students should be able to view and edit documents uploaded by them, and view documents uploaded by teachers, but not view the documents uplaoded by other students! Updated files: i. modules/SMSDocument/SMSDocument.php => define functions "ACLAccess" and "isOwner" to look up ownership also taking into account views 12. Not show the buttons which are inactive (like the Course detailview) or active but after clicking a message showing the record is not editable by the user Updated files: i. include/language/$language.lang.php => ['smsgroups'][$smsgroup]['hide_edit'] is defined ('none' for 'student') ii. modules/SMSDocument/DetailView.php => set the 'HIDE_EDIT_BUTTONS' template variable ii. modules/SMSDocument/DetailView.html => set the 'display' feature of a extra 'div' surrounding the buttons to 'HIDE_EDIT_BUTTONS' NOTE: this is also done for user settings and 'my account' display settings 7. Entrance fee assigning valid_period is read from the Course settings (month & years). Currently default value is 1 year i. from FEES to PERSONAL FEES 1. Not assigned if the student attended a class within valid_period 2. Not assigned if a transaction for entrance fee (type_id='6') exists within valid_period 8. Dealing with subpanels A. Forcing the page so refresh after a relation is deleted Updated files: i. modules/$module/layout_defs.php -> the following line may be added into definitions 'refresh_page_delete'=>1, // if set to 1 refreshes the whole page ii. modules/data/SugarBean.php -> in function 'process_list_query' add following line if (isset($this->refresh_subpanel_delete)) $temp->refresh_subpanel_delete=$this->refresh_subpanel_delete; iii. include/ListView/ListHandlerParent.php -> in fucntion 'ProcessListView' add following lines if (isset($this->refresh_subpanel_delete)){ $this->ListView->refresh_subpanel_delete=$this->refresh_subpanel_delete; iv. include/SubPanel/SubPanel.php -> in fucntion 'ProcessCustomSubPanelListView' add following lines if (isset($this->subpanel_defs->_instance_properties['refresh_page_delete'])){ $listview_handler->focus->refresh_subpanel_delete=$this->subpanel_defs->_instance_properties['refresh_page_delete']; $listview_handler->refresh_subpanel_delete=$this->subpanel_defs->_instance_properties['refresh_page_delete']; } v. B. Sending a special $_REQUEST variable when a subpanel is clicked (for changing the query for the popup) a. Define a new widget and add an '&html_var' into the calling address e.g. include/generic/SugarWidgets/SugarSubPanelTopSelectEventInstanceButton.php -> e.g. add following line $initial_filter = "&attandence"; 9. Dealing with the order buttons for the subpanel listviews Currently order buttons are not working properly. For Fee and Transaction subpanel for the Course module, temporarily order_by statement coming from the session is closed => After the orders buttons are fixed this should be re-addressed!!! 10. first_name - last_name order Unchanged modules: Leads, Prospects, Tasks, // begin metehan 0331 // end metehan 11. How subpanel queries are generated and how joined fields are generated for ordinary subpanels Case: ProspectLists module & contacts subpanel We shoud add the fields we would like to show in the subpanel definition, here 'modules/Contacts/subpanels/ForTargetLists.php' Then the function 'create_new_list_query' creates the necessary query for the joins. Here we should join the below tables to get the account name for the Contacts in the list: prospect_lists -> prospect_lists_prospects -> contacts -> accounts_contacts -> accounts Actual file: data/SugarBean.php => in function 'get_union_related_list' at line 1392 $related_field_name = $this_subpanel->get_data_source_name(); // get the relation name set by 'get_subpanel_data' here it is 'contacts' $parentbean->load_relationship($related_field_name); $query_array = $parentbean->$related_field_name->getQuery(true,array(),0,'',true); Actual file: data/SugarBean.php => in function 'create_new_list_query' at line 1643 if($data['type'] == 'relate' && isset($data['link'])) // this function generates necessay query values for the right-hand-side module. i.e. 'Contact' // however only if the field is included within this specific subpanel definition, i.e. 'ForTargetLists' // since 'account_name' is included, generated query includes a join with 'accounts' table, // but not a join with 'users' table since 'assigned_to' field is included within the subpanel definition 12. Dealing with the query condition for the contacts ==> HOW TO RETRIEVE & SHOW CONTACTS OTHER THAN STUDENTS, TEACHERS i. we have a field in the global $app_list_strings['smsgroups'] array: 'show_in_contacts' the queries in the Contact and other modules are constructed automatically to exclude the contact from the categories of which 'show_in_contacts' field is false ii. However for the ordinary subpanels, we have to add the extra conditions into the definition of the suppanel using the 'where' field If a new category which will not be shown in the Contact suppanels, we have to update the subpanels accordingly!!! EMAIL ENCODING PROBLEM DONE LIST: 1. Email encoding problem for JP emails Basicly encode header and body. But when encoding to or from names, only name part should be encoded not the addres between '<' and '>'!!! Updated files: i. modules/Email/Email.php -> in function 'send' headers (from_name, subject) are encoding with "iso-2022-jp" and body also with "iso-2022-jp" -> in function 'parse_addrs' -> name handling there are two cases to name is get from 'Contacts' list and directly input by user 1. from 'Contacts' list -> $to_addrs_names_arr[$i] variable includes name only, so use this name 2. user directly inputs names like 'Ahmet ', in this case extact also name part, i.e. Ahmet in this example ii. include/phpmailer/class.phpmailer.php -> default charset is set to "iso-2022-jp" -> in function 'EncodeString' before base64 encoding string is converted into "iso-2022-jp" encoding PROBLEM for hotmail --> it seems that hotmail needs the character encoding declaration to "iso-2022-jp" when it is set to "JIS" does not work properly. PROBLEM for yahoo: does not work properly --> use yahoo.co.jp IT IS NOT EASY TO SEPERATE HEADER HANDLING AND SUBJECT HANDLING FOR SMTP --> TRY WITH SENDMAIL 2. Showing the email contents properly in the program in UTF and getting rid of toggle button for showing/hiding contents Updated files: i. modules/Emails/DetailView.html ii. modules/Emails/DetailViewSent.html PENDING: 3. Making the html editor fully multilingual ==> DO LATER !!!! Updated files: i. include/htmlarea.php --> 'display' function takes the language as a variable ii. include/htmlarea/htmlarea.js --> multlingual handling of paragraph types iii. modules/Emails/EditView.php --> html area is called with languag variable -> 'en_us' is changed to 'en' iv. modules/EmailTemplates/EditView.php --> html area is called with languag variable -> 'en_us' is changed to 'en' PENDING: Help file is still in English only. CAMPAIGN EMAIL ENCODING PROBLEM DONE LIST: 1. Sending the campaign emails in the correct encoding Updated files: i. modules/EmailMan/EmailMan.php --> subject, from_name, to_name and body are JIS encoded 2. Sending the campaign emails in the correct encoding Updated files: i. modules/EmailMan/EmailMan.php --> subject, from_name, to_name and body are JIS encoded --> check for the 'iso-2022-jp' => JIS does not work properly for headers for HOTMAIL accounts ==> changed 3. Encoding problem for the Campaign emails: Initially templates are html encoded and special characters we put into the campaign emails. They are converted back to html entities. Updated files: i. modules/EmailMan/EmailMan.php ISSUES WITH EMAILS-CAMPAIGNS-EMAILTEMPLATES OTHER THAN ENCODING DONE LIST: 1. Setting the STMP settings => this part is used for campaign emails and should be set according to the server's specs. Updated files: include/phpmailer/class.phpmailer.php i. host: localhost ii. port: 25 iii. authenticate: --> not check for 'technopian/demo' site --> insert proper values for 'localhost' 2. Problem in email templates --> custom fields are not taken properly CHECK AGAIN PROPERLY!!! Updated files: i. modules/EmailTemplates/EmailTemplate.php 8. Problem in email templates --> custom fields are not taken properly Updated files: i. modules/EmailTemplates/EmailTemplate.php 7. Making the templates for the drop-down lists work correctly. Updated files: FOR EMAILS: i. modules/EmailTemplates/EmailTemplates.php --> $app_list_strings is declared as global variable --> depending on the case whether this is called from Emails or EmailMan (campaign related), '$translated' becomes an array or a string. Case handled seperately. FOR CAMPAIGNS ii. modules/EmailMan/EmailMan.php --> $app_list_strings is declared as global variable iii. emailmandelivery.php --> $app_list_strings is declared as global variable and retrieved using return_app_list_strings_language("ja") function, CURRENTLY "ja" IS HARDCODED!!! 3. Getting rid of error for the emailmandelivery.php file which is put into the cronejob for sending campaign emails Updated files: i. data/SugarBean.php 6. Campaigns: DETAILED TEST ==> seems to corrected in new version --> CHECK!!!! - Campaign mails are not going to the address checked as 'No Emails' (for direct emails no problem) - modules/EmailMarketing/Save.php --> all contacts were selected; updated to exclude deleted contacts - modules/EmailMarketing/Save.php --> all prospect_list were selected; updated to exclude deleted prospect_lists 10. Showing only some fields for selection in the EmailTemplate Editview Add showemailtemplate type into the vardefs.php of Contacts & Accounts and process accordingly Updated files: i. modules/EmailTemplates/EditView.php ii. modules/Accounts/vardefs.php iii. modules/Contacts/vardefs.php 14. Subject fields of emails and email templates are made not accepting newline Updated files: i. modules/Emails/EditView.html iii. modules/EmailTemplates/EditView.html 16. Parent field of an email is set to 'Contacts' as default Updated files: i. modules/Emails/EditView.html i. modules/Emails/EditViewArchive.html 17. Make the 'Email List' as the default view instead of 'My inbox' and change the menus Updated files: i. modules/Emails/ListView.php ii. modules/Campains/Menu.php iii. modules/EmailTemplates/Menu.php iv. modules/ProspectLists/Menu.php v. modules/Prospects/Menu.php ii. modules/Emails/Menu.php 13. Removing the text part of emails Updated files: i. modules/Emails/EditView.html --> get rid of the html edit part, button for toggle between text & html part ii. modules/EmailTemplates/EditView.html iii. modules/EmailTemplates/DetailView.html iv. modules/Emails/EditViewPro.js --> this puts the template contents into a email => text part is excluded ==> FILE ADDED v. include/htmlarea/htmlarea.js --> add JP fonts & make status bar disappear by unsetting 'this.statusBar' 18. Settings for being able to send campaign emails: i. Set the default SMTP settings both system level and user level (for the time being users get their SMTP settings from the config file!) ii. Create a mailbox of which 'Possible Actions' is 'Bounce Handling' Do not forget to enter a 'Sender' email address in this setting PENDING: 4. Making the 'remove yourself from the list' message at the bottom of the campaign email message multilingual Updated files: i. modules/EmailMan/EmailMan.php --> message is changed into JP PROBLEM: Not multilingual yet, get $mod_strings array from the language file (since ./emailmandelivery.php is callding this file from cronejob, global variables are not set properly) 5. 'emailmandelivery.php' file is no longer accessable from the web browsers -> it is redirected to index.php file within the '.htaccess' file That feature is temporarily turned off THEREFORE '.htaccess' FILE SHOULD BE UPDATED BEFORE UPLOADING 12. Problem for email templates when a field is empty (for Accounts module) Updated files: STILL PENDING 13. Making 'emailmandelivery.php' and 'removeme.php' files multilingual Since they are not run within the program, they do not refer to the language files and user's preferrec language! NOTE for EMAILS: - Handling the localhost (emailmandelivery) and the server settings Updated files: i. modules/Emails/Email.php --> line 994 => 'mail_smtpauth_req' check is excluded for localhost servers 14. Adding an extra form field into the popup windows => example adding personal fees when a student is added via the Course's 'student' subpanel Add a function into the subpanel module, here within the 'Student' module 'add_field_to_popup' function Updated files: i. modules/Student/Student.php With this function we are able to designate whether the fee should be assigned to the student and what the sell date is! this function adds extra input form fields into the students popup window additional parameter should start with 'add_field_to_popup' string!! ii. include/javascript/popup_helper.js => function 'send_back_selected' -> form elements starting with 'add_field_to_popup' are added into the call_back_function for this case call_back_function was 'set_return_and_save_background' therefore iii. include/SubPanel/SubPanelTiles.js => function 'set_return_and_save_background' -> form elements are added into the returning module as the POST elements iv. include/generic/Save2.php => those parameters are passed as $_REQUEST variables and used in the returning function 15. Adding a special function when a relationship is saved Example: if a student's status is application, i.e. that person is not a regular student yet, we would like to have its 'event_contact_status' to be set to 'application' when he/she is added into the student list of a course. Similarly, fees should not be assigned to the person. Updated files: i. include/generic/Save2.php => 'handle_relationship_special' field is added into '$additional_values' array ii. data/Link.php => in function '_insert_row' if the above field is set, the function 'handle_relationship_special' in the current module is called (if exists) iii. modules/Course/Course.php => in function 'handle_relationship_special' status of the student is checked iv. modules/Course/Course.php => function 'add_personal_fees' is updated accordingly 16. Forcing to have each transaction to have a different fee_id (except the installment payments) For Transaction module, get rid of 'Duplicate' button and do not allow to edit 'course_id' for transactions and allow to edit 'contact_id' only for a new transaction Updated files: i. modules/Transaction/DetailView.html => get rid of 'Duplicate' button ii. modules/Transaction/include/EditViewClass.php => make the 'course_id' field disabled and 'contact_id' field disabled for non-new transactions iii. modules/Transaction/EditView.html => same as the above line When a fee is applied to a student, duplicate the fee with a new 'fee_id' and a number to the description and use the new created fee for creating the transaction(s). Updated files: i. 'sms_fee' table in DB => add the new 'applied_contact' field UPDATE sms_fee, sms_transaction SET sms_fee.applied_contact=1 WHERE sms_fee.deleted =0 AND sms_transaction.deleted =0 AND sms_fee.id = sms_transaction.fee_id ; ii. modules/Course/Course.php => 'only_nonapplied' parameter is added to 'get_fees' function to get only non 'contact_applied' fees of a person for a class iii. modules/Keiri/include/keiri.php => updated 'calculate_monthly_fees' and 'clear_seikyu_payment' functions -> when a 'do seikyu' is done all fees without a transaction date are deleted and 'applied_contact' field of related fees are updated properly -> /////// POPUPS /////// 1. FOR SUBPANEL POPUPS e.g. 'Select' button of Course's Student subpanel include/SubPanel/SupPanelTiles.php => 'get_buttons' function get the buttons from the widget file, here; include/generic/SugarWidgets/SugarWidgetSubPanelTopSelectStudentButton.php => when button is clicked a javascript function is called open_popup(\"$this->module_name\",600,400,\"$initial_filter\",true,true,$json_encoded_php_array,\"$popup_mode\",$create) $json_encoded_php_array icludes the $popup_request_data $popup_request_data = array( 'call_back_function' => 'set_return_and_save_background', ==> this function is used as the call-back function !!! 'form_name' => 'DetailView', 'additional_sms' => 'zzz', // begin metehan 0412 'field_to_name_array' => array( 'id' => 'subpanel_id', 'add_field_to_popup' => '1', ), 'passthru_data' => array( 'child_field' => $subpanel_name, 'return_url' => urlencode($return_url), 'link_field_name' => $link_field_name, 'module_name' => $subpanel_name, 'refresh_page'=>$refresh_page, ), ); Here the elements in $popup_request_data are used in the popup window except the 'passthru_data' which is passed to the parent window we can add extra filters by using $initial_filter like $initial_filter="&add_field_to_popup" include/javascript/popup_parent_helper.js => this javascript file includes the 'open_popup' function which prepares the URL and calls it: function open_popup(module_name, width, height, initial_filter, close_popup, hide_clear_button, popup_request_data, popup_mode, create, metadata, smsgroup) window.document.popup_request_data = popup_request_data; -> set the global 'popup_request_data' from the parameters URL+='&metadata='+metadata; -> put 'metadata' into the GET variables for the popup window modules/Student/Popup.php ==> if we have 'add_field_to_popup' set by the button widget, we process the popup specially, e.g. always multiselects etc. if(!empty($_REQUEST['html'])) { ........ elseif($_REQUEST['html'] == 'add_field_to_popup') echo $popup->process_page_additional(); include/Popups/PopupPicker.php => 'process_page' is called by the main index file $form = new XTemplate('modules/Student/Popup_pickerCourse.html'); within the 'modules/Student/Popup_pickerCourse.html' -> the contents of the request data is put into the form var if (!empty($_REQUEST['mode']) && strtoupper($_REQUEST['mode']) == 'MULTISELECT') { ==> if the popup window type is multiselect, button is created IMPORTANT: in order to have additional fields to be carried after a search is performed, this condition is raised ==> this is logical since we need multiple selects even after a search is performed ==> SugarCRM assumes that after a search is performed there is no need for multiselect popup windows, so it explicitely makes the second window single select!!! $multi_select=true; $button .= "xTemplate->assign("ONCLICK_END","');\" "); } include/javascript/popup_helper.js => this javascript file includes the 'send_back_selected' and 'send_back' functions basically send_back is for single return processing whiel send_back_selected is for multiselects (for email popups 'modules/Emails/email_popup_helper.js' file is used which includes same named functions with an extra parameter i.e. 'field_to_name_array') function send_back_selected(module, form, field, error_message) for (i = 0; i < form.elements.length; i++){ ==> here the checked values are added into the array_contents array to be send by GET if(form.elements[i].name == field) { if (form.elements[i].checked == true) { ++j; array_contents.push('"' + "ID_" + j + '":"' + form.elements[i].value + '"'); } } // else if (form.elements[i].name.indexOf('add_field_to_popup') >= 0) { ==> here we may add additional form elements into the same array // add_field_data[form.elements[i].name] = form.elements[i].value; } eval("var selection_list_array = {" + array_contents.join(",") + "}"); ==> generate the selection list array var result_data={"form_name":form_name,"selection_list":selection_list_array ,"passthru_data":passthru_data}; ==> prepare the parameters // begin metehan 0401 result_data['add_field_to_popup'] = add_field_data; ==> and finally call the call-back function call_back_function(result_data); 2. FOR NON-SUBPANEL POPUPS e.g. 'Select' button of Email's Student subpanel modules/Emails/EditView.php ==> buttons for the popup is prepared $change_to_addrs_button = '\n"; $xtpl->assign("CHANGE_TO_STUDENT_ADDRS_BUTTON", $change_to_addrs_button); ==> request data is prepared $popup_request_data = array( 'call_back_function' => 'set_return', 'form_name' => 'EditView', 'field_to_name_array' => array( 'id' => 'assigned_user_id', 'user_name' => 'assigned_user_name', ), ); $xtpl->assign('encoded_users_popup_request_data', $json->encode($popup_request_data)); modules/Emails/EditView.html ==> {CHANGE_TO_STUDENT_ADDRS_BUTTON} ==> button is put into the xtemplate file modules/Emails/EditView.js ==> smsgroup parameter is added into the function definition function button_change_onclick(obj, smsgroup) if (smsgroup) { var popup_request_data = { "call_back_function" : "set_email_return", "form_name" : "EditView", "smsgroup" : smsgroup, ==> this line is added "field_to_name_array" : { "id" : prefix + "addrs_ids", "email1" : prefix + "addrs_emails", "name" : prefix + "addrs_names", "email_and_name1" : prefix + "addrs_field" } }; return open_popup("Contacts",600,400,filter,true,false,popup_request_data,'MultiSelect',false,'popupdefsEmail', smsgroup); ==> smsgroup parameter is added } else { var popup_request_data = { "call_back_function" : "set_email_return", "form_name" : "EditView", "field_to_name_array" : { "id" : prefix + "addrs_ids", "email1" : prefix + "addrs_emails", "name" : prefix + "addrs_names", "email_and_name1" : prefix + "addrs_field" } }; return open_popup("Contacts",600,400,filter,true,false,popup_request_data,'MultiSelect',false,'popupdefsEmail'); } include/javascript/popup_parent_helper.js ==> smsgroup parameter is added into the function definition function open_popup(module_name, width, height, initial_filter, close_popup, hide_clear_button, popup_request_data, popup_mode, create, metadata, smsgroup) if (smsgroup && smsgroup != '' && smsgroup != 'undefined') { ==> if smsgroup is defined it is added into the URL GET variables URL+='&smsgroup='+smsgroup; } 3. Remembering selected items through pages within popups ==> cancelled now include/ListView/ListView.php ==> paging was not working properly for 'multiselect' popups --> special processing is raised at lines 990 & 1005 function processListNavigation // begin metehan 0412 ==> just raised this condition!!! if($this->multi_select_popup and false) { // nav links for multiselect popup, submit form to save checks. IMPORTANT: the logic was to save the checked values first before advancing to a new page for multiselect popups ==> this condition is raised !!! 4. Handling the 'metadata' definitions for popups metadata definitions are stored under the 'modules/$module/metadata' folder EXAMPLE: having different search titles and list titles for the popups shown in the Email EditView screen - All email address selection buttons are defined in 'modules/Email/EditView.php' file ==> basically they call the 'Contacts' popups with sms parameter - 'modules/Email/EditView.js' contains javascript functions and sets the popup metada according to the smsgroup parameter if (smsgroup == 'student') return open_popup("Contacts",600,400,filter,true,false,popup_request_data,'MultiSelect',false,'popupdefsEmailStudent',smsgroup); - Metadefinitions are read in the constructor of the 'Popup_Picker' class ==> here 'include/Popups/Popup_picker.php' function Popup_Picker() { global $currentModule; if(!empty($_REQUEST['metadata']) && $_REQUEST['metadata'] != 'undefined') // if custom metadata is requested require_once('modules/' . $currentModule . '/metadata/' . $_REQUEST['metadata'] . '.php'); else require_once('modules/' . $currentModule . '/metadata/popupdefs.php'); - The following line carries the 'metadata' variable through popup windows when search button is clicked within the 'include/Popups/Popup_picker.php' file function process_page() $form->assign('metadata', empty($_REQUEST['metadata']) ? '' : $_REQUEST['metadata']); - Include the below line in the xtemplate file in order to the above effect ==> this the default file or the template file set in the meta definition 'modules/Contacts/EmailPicker.html' ////// END POPUPS ////////// 16. Copy address button on the 'accounts' detailview is deleted Updated file: i. modules/Accounts/DetailView.html ==> below lines are deleted {PUSH_CONTACTS_BILLING} {PUSH_CONTACTS_SHIPPING} 17. Linking the subpanel with the parent for custom subpanels! Here the example is the SMSDocument subpanel for the Courses. You can also add custom where conditions like the ordinary subpanels. Updated files: i. modules/Course/layout_defs.php ==> designate the parent module of the subpanel 'smsdocument' => array( 'custom_parent' => 'parent_id', // begin metehan 0413 'is_custom'=>true, ), ii. modules/SMSDocument/include/ListViewClass.php ==> add the parent condition for custom subpanels function CreateWhereClause(){ if( (isset($_REQUEST['query'])) || !empty($this->custom_subpanel_definition->_instance_properties['custom_parent']) || !empty($this->custom_subpanel_definition->_instance_properties['custom_where']) ) { $this->AssignRequestVars(); $this->SetWhereClauses(); // defined in the extending class } } function SetWhereClauses($smsgroup='') { if ($this->is_custom && !empty($this->custom_subpanel_definition->_instance_properties['custom_parent']) ) { $custom_parent = $this->custom_subpanel_definition->_instance_properties['custom_parent']; array_push($this->where_clauses, $this->focus->table_name . "." . $custom_parent . " = '" . $this->custom_subpanel_parent_id . "'"); } if ($this->is_custom && !empty($this->custom_subpanel_definition->_instance_properties['custom_where']) ) { array_push($this->where_clauses, $this->custom_subpanel_definition->_instance_properties['custom_where'] ); } ///////// ADDING SCHOOL BRANCHES TO THE SYSTEM //////////// CHANGES ON THE DATABASE 1. Add 'school_id' field on the following tables contacts, resources, events 2. Add the 'users_schools' table into DB ==> this table show which school's data the user has access to ASSUMPTIONS 1. The ID 'sssssss-1111' is reserved for the first school ==> used in the program for some cases 2. When a user does not have a school in the access list, i.e. there is no row in the 'users_schools' table with the user's id The 'school_id' in the 'contacts' table will be used. One example would be the students INFO Aoyama School ID sssssss-1111 Ginza School ID 483794c4-adee-a607-f685-4441c943a1e2 Ometosando School ID 58362bd0-5d1e-c3f9-efd1-4441c972601c ///////////////////////////////////////////////////////////////////////////////////////// CHANGES IN THE PROGRAM /////////////////////////////////////// LISTVIEWS FOR DERIVED CLASSES: Here 'Student' class is taken as the example --> similarly applied to Teacher & Staff class Updated files: i. modules/Student/SearchForm.html => school pull-down menu is added {APP.LBL_SCHOOL}  {SCHOOL_SELECT_OPTIONS} ii. modules/Users/User.php function get_school_options() { => create the school pull-down menu function get_users_school_id() { => get the user's school_id iii. include/Listview/ListhandlerParent.php function AssignXtplVars() { => assign the Xtemplate variable global $current_user; $this->search_form->assign("SCHOOL_SELECT_OPTIONS", $current_user->get_school_options()); function AssignRequestVars() { => assign request variable if (isset($_REQUEST['get_school_id'])) $this->school_id = $_REQUEST['get_school_id']; function WhereClauseGeneric() { => do the query according to the school_id if(isset($this->school_id) && $this->school_id != "") { array_push($this->where_clauses, "contacts.school_id like '".PearDatabase::quote($this->school_id)."%'"); } elseif (!$this->is_custom) { => necessary for not screening for the custom subpanels global $current_user; array_push($this->where_clauses, "contacts.school_id like '".PearDatabase::quote($current_user->get_users_school_id())."%'"); } FOR POPUPS 1. If the module has its own Popup definition ==> e.g. for the Course's teacher subpanel Updated files: i. modules/Teacher/Popup_picker.html ==> first add the pull-down {APP.LBL_SCHOOL} {SCHOOL_SELECT_OPTIONS} ii. modules/Contacts/Popup_picker.html ==> add the Xtemplate var for the pull-down function process_page() global $current_user; $form->assign('SCHOOL_SELECT_OPTIONS', $current_user->get_school_options()); iii. modules/Teacher/Popup_picker.php ==> assign the request variable function _get_where_clause() if (isset($_REQUEST['get_school_id'])) { array_push($where_clauses, "contacts.school_id like '".PearDatabase::quote($_REQUEST['get_school_id'])."%'"); } else { global $current_user; array_push($where_clauses, "contacts.school_id like '".PearDatabase::quote($current_user->get_users_school_id())."%'"); } 2. If the module uses the general Popup definition ==> e.g. for the Email's teacher popup window Updated files: i. modules/Contacts/Email_picker.html ==> first add the pull-down {APP.LBL_SCHOOL} {SCHOOL_SELECT_OPTIONS} ii. include/Popups/Popup.php ==> add the Xtemplate var for the pull-down function process_page() global $current_user; $form->assign('SCHOOL_SELECT_OPTIONS', $current_user->get_school_options()); iii. include/Contacts/metadata/popupdefsEmailTeacher.php ==> add the following metada variable 'show_school_options' => true, iv. include/Popups/Popup.php ==> assign request variable for the school selection if the metada is set function _get_where_clause() if (isset($this->_popupMeta['show_school_options']) && $this->_popupMeta['show_school_options']) { if (isset($_REQUEST['get_school_id'])) { array_push($whereClauses, "contacts.school_id like '".PearDatabase::quote($_REQUEST['get_school_id'])."%'"); } else { global $current_user; array_push($whereClauses, "contacts.school_id like '".PearDatabase::quote($current_user->get_users_school_id())."%'"); } } 3. If we do not want to do school branch search for our derived modules e.g. we would like to show the school list anyway Updated files: i. modules/Resource/SearcFormSCHOOL.html i. modules/ListHandlerParent.php function WhereClauseGeneric() { if(isset($this->school_id) && $this->school_id != "" && !isset($_REQUEST['do_not_search_school']) ) { /////////////////////////////////////// FOR EDITVIEW AND DETAILVIEWS Updated files: i. modules/$module/vardefs.php ==> add 'school_id' and 'school_name' to the list ii. modules/$module/$module.php function fill_in_additional_detail_fields() ==> get the school name using the school_id --> for detailviews function create_list_query($order_by, $where, $show_deleted = 0, $extra_where = false) ==> add the school_name to the list resource.name as school_name "; // metehan 0417 INNER JOIN resource ON contacts.school_id = resource.id AND resource.deleted = 0 "; // metehan 0417 function create_custom_list_query($order_by, $where, $show_deleted) { ==> to be updated if we want to show school_name in custom subpanels iii. include/EditView/EditHandlerParent.php function SetTemplateVars() { ==> prepare the pulldown global $current_user; if (isset($this->focus->school_id)) $this->xtpl->assign("SCHOOL_SELECT_OPTIONS", $current_user->get_school_options('school_id', $this->focus->school_id)); else $this->xtpl->assign("SCHOOL_SELECT_OPTIONS", $current_user->get_school_options('school_id')); iv. modules/Users/User.php ==> if the user does not has acces to the person's school, the user cannot change the person's school!!! function get_school_options($var_name = 'get_school_id', $requested_selected_key = '') { if ($this->get_users_permission_to_school_id($selected_key)) return ""; else { $query = " SELECT resource.name as school_name from resource where id='$selected_key' AND deleted=0 "; $result = $this->db->query($query, true); if ($selected_school = $this->db->fetchByAssoc($result)) { return $selected_school['school_name']; } return ''; } /////////////////////////////////////// FOR COURSE & COURSECATEGORY Updated files: i. modules/CourseCategory/CategoryParent.php ==> set the Xtemplate var for the pulldown function process() global $current_user; $this->xtpl->assign("SCHOOL_SELECT_OPTIONS", $current_user->get_school_options()); ii. modules/CourseCategory/ListView.html iii. modules/CourseCategory/Popup_picker.html iv. modules/CourseCategory/Popup_picker_Course.html v. onchange="JavaScript:submit()" ///////////////////////////////////////// PERMISSIONS AND ROLES 1. To get the top header modules list properly shown, the following changes are made: Originally, the 'roles_users' table is used to get the user-roles relation. However, now this relation should be extracted from the 'acl_roles_users' table. modules/Role/Role.php ==> 'check_user_role_count' and 'query_user_allowed_modules' functions are changed //////////////////////////////////////// HOW TO PUT THE memo SUBPANEL FOR A MODULE Updated files: 1. vardefs.php into definition part: 'memo'=> array ( 'name' => 'memo', 'type' => 'link', 'relationship' => 'memo', 'vname' => 'LBL_MEMO', 'link_type' => 'one', 'module'=>'Memo', 'bean_name'=>'Memo', 'source' => 'non-db', ), into relationships part: change the left-hand-side module and table name accordingly 'memo' => array('lhs_module' => 'Course', 'lhs_table' => 'smsevent', 'lhs_key' => 'id', 'rhs_module' => 'Memo', 'rhs_table' => 'memo', 'rhs_key' => 'parent_id', 'relationship_type' => 'one-to-many'), 2. layout_defs.php just change the order of the subpanel => no need to add title_key into the mod_strings! 'memo' => array( 'order' => 28, 'module'=>'Memo', 'custom_subpanel_listview_handler_class_file' => 'modules/Memo/SubpanelListView.php', 'custom_subpanel_listview_handler_class'=>'ListHandler_Memo', 'title_key' => 'LBL_CONTACTS_SUBPANEL_MEMO_TITLE', 'custom_parent' => 'parent_id', // begin metehan 0413 'is_custom'=>true, 'get_subpanel_data' => 'memo', 'add_subpanel_data' => 'memo_id', 'top_buttons' => array( array('widget_class' => 'SubPanelTopCreateButton'), ), ), 3. DO NOT FORGET TO RUN "REPAIR RELATIONSHIPS' command from the admin menu // FILES UPDATED AFTER LAST FTP UPLOAD P data/SugarBean.php P include/MassUpdate.php P include/generic/SugarWidgets/SugarWidgetSubPanelTopSelectButton.php P modules/Resource/SubpanelListView.html P modules/SMSCounseling/layout_defs.php P modules/SMSEvent/vardefs.php // FILES UPDATED AFTER event_contact CHANGE 2010.12.01 ? KAIHATSU/ikkatsumail.sql ? SCHOOL_CUSTOM/macc/config.overrideHONBAN.php U config.biokura.honban.php U config.biokura.local.php U config.biokura.test.php U config.php U sms_start.php U KAIHATSU/UPDATE_DB.sql U SCHOOL_CUSTOM/akamon/modules/Course/SubpanelListViewEnroll.html U SCHOOL_CUSTOM/akamon/modules/Course/SubpanelListViewEnrollTeacher.html U SCHOOL_CUSTOM/asunaro/cache/custom/modules/Course/language/ja.lang.override.php U SCHOOL_CUSTOM/asunaro/cache/custom/modules/Student/language/ja.lang.override.php U SCHOOL_CUSTOM/asunaro/db_updates/dbupdates.sql P SCHOOL_CUSTOM/biokura/include/language/ja.lang.override.php U SCHOOL_CUSTOM/free/modules/Course/SubpanelListViewEnroll.html U SCHOOL_CUSTOM/free/modules/Student/SubpanelListViewEnroll.html U SCHOOL_CUSTOM/free/modules/Teacher/SubpanelListViewEnroll.html U SCHOOL_CUSTOM/hils/modules/Course/SubpanelListViewEnroll.html U SCHOOL_CUSTOM/kanebo/modules/Course/SubpanelListViewEnroll.html U SCHOOL_CUSTOM/misuzu/modules/Course/SubpanelListViewEnroll.html U SCHOOL_TYPES/culture/modules/Student/DetailView.html U SCHOOL_TYPES/culture/modules/Student/DetailViewCarte.html U SCHOOL_TYPES/culture/modules/Student/EditView.html P SCHOOL_TYPES/culture/modules/Teacher/DetailView.html U SCHOOL_TYPES/culture/modules/Teacher/EditView.html P data/Link.php U data/SugarBean.php U include/ListView/ListHandlerParent.php U include/generic/CustomEditRelationship.php U include/generic/SaveRelationshipCls.php U include/generic/custom_edit_relationship.js U include/javascript/techno.js U include/language/common.php U include/language/en_us.lang.php U include/language/ja.lang.php U include/technoutils/technoutils_functions.php U metadata/event_contactsMetaData.php U metadata/event_contactsMetaData_biokura.php U modules/Course/SubpanelListView.html U modules/Course/SubpanelListViewBasic.html U modules/Course/SubpanelListViewBranch.html U modules/Course/SubpanelListViewEnroll.html U modules/Course/SubpanelListViewEnrollBranch.html U modules/Course/layout_defs.php P modules/EventInstance/layout_defs.php P modules/Exam/layout_defs.php U modules/Import/ImportFunctions.php U modules/Import/index.php U modules/Import/language/en_us.lang.php U modules/Import/language/ja.lang.php U modules/Import/manual_transaction/ImportStep.php U modules/Import/manual_transaction/ImportStep1.html U modules/Import/manual_transaction/ImportStep11.html U modules/Import/manual_transaction/ImportStep2.html U modules/Import/manual_transaction/Import_ManualTrans.php U modules/Import/manual_transaction/Import_ManualTrans_biokura.php U modules/Import/manual_transaction/config.php U modules/Import/manual_transaction/config_biokura.php U modules/SMSEvent/EditViewContactEventRelation.html U modules/SMSEvent/EditViewContactEventRelationWithoutSchedule.html U modules/SMSEvent/SubpanelListView.html P modules/SMSEvent/layout_defs.php U modules/SMSSchedule/Schedule.php U modules/Staff/SubpanelListView.html P modules/Staff/SubpanelListViewParticipant.html P modules/Staff/layout_defs.php U modules/Student/SearchFormCourses.html U modules/Student/SubpanelListView.html U modules/Student/SubpanelListViewBasic.html U modules/Student/SubpanelListViewBranch.html U modules/Student/SubpanelListViewEnroll.html U modules/Student/SubpanelListViewEnrollBranch.html U modules/Student/layout_defs.php U modules/Student/include/ListViewClassCourse.php U modules/Teacher/SubpanelListView.html U modules/Teacher/SubpanelListViewBasic.html U modules/Teacher/SubpanelListViewEnroll.html P modules/Teacher/layout_defs.php U modules/Transaction/TransImportManual.php U modules/Transaction/TransProcessManual.php U modules/Transaction/html/TransProcessManual.html U modules/Transaction/include/TransProcessManualCls.php U modules/Transaction/include/TransProcessManualCls_biokura.php -- local PC wampserver & ioncode decoder installation install two files under directory "\\nas\public\software\Development" 1. WampServer2.0f.exe 2. WampServer2-PHP5211.exe install ioncube loader using the below file under directory "\\nas\public\software\Development\LOCAL SMS PC" ioncube_loaders_setup.exe PROBLEMS: 1. Sending an email Using IIS service for local SMTP server will be 127.0.0.1 and port will be 25 XP -> http://www.ehow.com/how_4489548_set-up-smtp-server-windows.html Vista -> http://learn.iis.net/page.aspx/751/configure-smtp-e-mail-in-iis-7-and-above/