diff --git a/languages/en_us/Vtiger.php b/languages/en_us/Vtiger.php index 0e4bc08b1ca2a08d8a8c720082feb154eda8b0c5..20c2bfa09e51a181c4c5aafba7e290496a7b58a1 100644 --- a/languages/en_us/Vtiger.php +++ b/languages/en_us/Vtiger.php @@ -1934,4 +1934,5 @@ $jsLanguageStrings = array( 'JS_PASSWORD_MISMATCH_ERROR' => 'Please re-enter passwords. The "new password" and "confirm password" values do not match.', 'LBL_LIST_DELETE_CONFIRMATION' => 'Are you sure you want to delete?', 'JS_WIDGET_RESIZING_WAIT_MSG' => 'Widget contents will load after resizing.', + 'JS_COPIED_SUCCESSFULLY' => 'Copied successfully', ); diff --git a/layouts/v7/modules/Calendar/resources/Calendar.js b/layouts/v7/modules/Calendar/resources/Calendar.js index b04334ac2e7b76b2b6a2078352f8f999bddbd70c..0b938b775ac4a70758f3f6c50927d3d0f8d16aaf 100644 --- a/layouts/v7/modules/Calendar/resources/Calendar.js +++ b/layouts/v7/modules/Calendar/resources/Calendar.js @@ -1569,16 +1569,41 @@ Vtiger.Class("Calendar_Calendar_Js", { var thisInstance = this; var userDefaultActivityView = thisInstance.getDefaultCalendarView(); var userDefaultTimeFormat = thisInstance.getDefaultCalendarTimeFormat(); + + var dateFormat = app.getDateFormat(); + //Converting to fullcalendar accepting date format + var monthPos = dateFormat.search("mm"); + var datePos = dateFormat.search("dd"); + if (monthPos < datePos) { + dateFormat = "M/D"; + } else { + dateFormat = "D/M"; + } + var calenderConfigs = { header: { left: 'month,agendaWeek,agendaDay,vtAgendaList', center: 'title', right: 'today prev,next', }, + columnFormat: { + month: 'ddd', + week: 'ddd '+dateFormat, + day: 'dddd '+dateFormat + }, views: { - vtAgendaList: { - duration: {days: Calendar_Calendar_Js.numberOfDaysInAgendaView} - } + vtAgendaList: { + duration: {days: Calendar_Calendar_Js.numberOfDaysInAgendaView} + }, + month:{ + columnFormat:'ddd' + }, + agendaWeek: { + columnFormat: 'ddd ' + dateFormat + }, + agendaDay: { + columnFormat: 'dddd '+dateFormat + } }, fixedWeekCount: false, firstDay: thisInstance.daysOfWeek[thisInstance.getUserPrefered('start_day')], diff --git a/layouts/v7/modules/Vtiger/AddCommentFooter.tpl b/layouts/v7/modules/Vtiger/AddCommentFooter.tpl index 24387c8b5a95d9c8921fe9a8364717def5e0fac4..9986e67a4d0992dd41a7cef82933ba2127e4c868 100644 --- a/layouts/v7/modules/Vtiger/AddCommentFooter.tpl +++ b/layouts/v7/modules/Vtiger/AddCommentFooter.tpl @@ -13,7 +13,9 @@ <div class="modal-footer"> <div class="row-fluid"> <div class="col-xs-6"> - {include file=vtemplate_path($FIELD_MODEL->getUITypeModel()->getTemplateName(),$MODULE_NAME)} + {if $FIELD_MODEL->getProfileReadWritePermission()} + {include file=vtemplate_path($FIELD_MODEL->getUITypeModel()->getTemplateName(),$MODULE_NAME)} + {/if} </div> <div class="col-xs-6"> <div> diff --git a/layouts/v7/modules/Vtiger/RecentComments.tpl b/layouts/v7/modules/Vtiger/RecentComments.tpl index a12f69e17f7c8aafba90529c2e9fea5d1e58f895..5ec4bdb7f9d45364753eaf73a1eb446b94339c4f 100644 --- a/layouts/v7/modules/Vtiger/RecentComments.tpl +++ b/layouts/v7/modules/Vtiger/RecentComments.tpl @@ -38,9 +38,11 @@ <button class="btn btn-success btn-sm detailViewSaveComment" type="button" data-mode="add">{vtranslate('LBL_POST', $MODULE_NAME)}</button> </div> </div> - <div class="col-xs-6 pull-left"> - {include file=vtemplate_path($FIELD_MODEL->getUITypeModel()->getTemplateName(),$MODULE_NAME) MODULE="ModComments"} - </div> + {if $FIELD_MODEL->getProfileReadWritePermission()} + <div class="col-xs-6 pull-left"> + {include file=vtemplate_path($FIELD_MODEL->getUITypeModel()->getTemplateName(),$MODULE_NAME) MODULE="ModComments"} + </div> + {/if} </div> </div> {/if} diff --git a/layouts/v7/modules/Vtiger/ShowAllComments.tpl b/layouts/v7/modules/Vtiger/ShowAllComments.tpl index ec07af50a88fa12b4b4f7a303fddf8712559c2b7..3cab0f50d5311d2f193b35cbc59fa07c3580beb3 100644 --- a/layouts/v7/modules/Vtiger/ShowAllComments.tpl +++ b/layouts/v7/modules/Vtiger/ShowAllComments.tpl @@ -30,9 +30,11 @@ <button class="btn btn-success btn-sm saveComment" type="button" data-mode="add"><strong>{vtranslate('LBL_POST', $MODULE_NAME)}</strong></button> </div> </div> - <div class="col-xs-8 pull-left"> - {include file=vtemplate_path($FIELD_MODEL->getUITypeModel()->getTemplateName(),$MODULE_NAME) MODULE="ModComments"} - </div> + {if $FIELD_MODEL->getProfileReadWritePermission()} + <div class="col-xs-8 pull-left"> + {include file=vtemplate_path($FIELD_MODEL->getUITypeModel()->getTemplateName(),$MODULE_NAME) MODULE="ModComments"} + </div> + {/if} </div> </div> </div> diff --git a/layouts/v7/resources/application.js b/layouts/v7/resources/application.js index dc2188cdaf9106cb58910ad78890a74aec937094..e3117227d7e28964474e53dda879f909218194e1 100644 --- a/layouts/v7/resources/application.js +++ b/layouts/v7/resources/application.js @@ -111,6 +111,23 @@ window.app = (function () { params.data = app.convertUrlToDataParams(params.url); delete params.url; } + + /** + * Safari 11.1 - ajax/XHR form submission will fail if input[type=file] is empty in formData. + */ + var isIOSDevice = navigator.userAgent.match(/iPhone|iPod|iPad/i) != null; + if ((!!window.safari === true || isIOSDevice) + && params.data instanceof FormData && typeof params.data.getAll == 'function') { + var fileNameAttribute = (params.data.getAll("filename[]").length > 0) ? 'filename[]' : 'file[]'; + var fileNames = params.data.getAll(fileNameAttribute); + params.data.delete(fileNameAttribute); + jQuery.each(fileNames, function (key, fileNameObject) { + if (fileNameObject.name) { + params.data.append(fileNameAttribute, fileNameObject); + } + }); + } + this._request(params).then(function (err, data) { return aDeferred.resolve(err, data); }); diff --git a/layouts/v7/resources/helper.js b/layouts/v7/resources/helper.js index 4602b8bf95484eb83b73f64921deabee0e537fca..58ffff39b002260e530783ee645da137ddce2f03 100644 --- a/layouts/v7/resources/helper.js +++ b/layouts/v7/resources/helper.js @@ -436,7 +436,7 @@ jQuery.Class("Vtiger_Helper_Js",{ if(typeof cb === "function") { container.off('shown.bs.modal'); //This event is fired when the modal has been made visible to the user - container.on('shown.bs.modal', function () { + container.one('shown.bs.modal', function () { cb(container); }); } diff --git a/pkg/vtiger/modules/SMSNotifier/languages/en_us/Settings/SMSNotifier.php b/pkg/vtiger/modules/SMSNotifier/languages/en_us/Settings/SMSNotifier.php index e3f029b84ca13cefac131315ba1856f80d72ff40..215aea6cdf66c71719253c02b550541373bf2edf 100755 --- a/pkg/vtiger/modules/SMSNotifier/languages/en_us/Settings/SMSNotifier.php +++ b/pkg/vtiger/modules/SMSNotifier/languages/en_us/Settings/SMSNotifier.php @@ -17,6 +17,9 @@ $languageStrings = array( 'providertype' => 'Provider', 'SMSNotifier' => 'SMS Provider Configuration', 'username' => 'User Name', + 'ClickATellNew' => 'Clickatell (Platform)', + 'ClickATell' => 'Clickatell (Communicator/Central)', + 'LBL_CLICKATELLNEW_CALLBACKURL_INFO' => "Please copy this URL to the 'Enable delivery notifications' field in your ClickATell SMS Integration Settings page", ); $jsLanguageStrings = array( diff --git a/pkg/vtiger/modules/SMSNotifier/layouts/v7/modules/Settings/SMSNotifier/ClickATellNew.tpl b/pkg/vtiger/modules/SMSNotifier/layouts/v7/modules/Settings/SMSNotifier/ClickATellNew.tpl new file mode 100755 index 0000000000000000000000000000000000000000..c00ee85af3827141affaec26c6d20c088fce4705 --- /dev/null +++ b/pkg/vtiger/modules/SMSNotifier/layouts/v7/modules/Settings/SMSNotifier/ClickATellNew.tpl @@ -0,0 +1,58 @@ +{*<!-- +/********************************************************************************* +** The contents of this file are subject to the vtiger CRM Public License Version 1.0 +* ("License"); You may not use this file except in compliance with the License +* The Original Code is: vtiger CRM Open Source +* The Initial Developer of the Original Code is vtiger. +* Portions created by vtiger are Copyright (C) vtiger. +* All Rights Reserved. +* +********************************************************************************/ +-->*} +{strip} + {foreach key=FIELD_NAME item=FIELD_MODEL from=$PROVIDER_MODEL} + <div class="col-lg-12"> + <div class="form-group"> + {assign var=FIELD_NAME value=$FIELD_MODEL->get('name')} + <div class = "col-lg-4"> + <label for="{$FIELD_NAME}">{vtranslate($FIELD_MODEL->get('label') , $QUALIFIED_MODULE_NAME)}</label> + </div> + <div class = "col-lg-6"> + {assign var=FIELD_TYPE value=$FIELD_MODEL->getFieldDataType()} + {assign var=FIELD_VALUE value=$RECORD_MODEL->get($FIELD_NAME)} + {if $FIELD_NAME == 'username' || $FIELD_NAME == 'password'} continue;{/if} + {if empty($FIELD_VALUE) and $FIELD_MODEL->get('value')} + {assign var=FIELD_VALUE value=$FIELD_MODEL->get('value')} + {/if} + + {if $FIELD_TYPE == 'picklist'} + <select class="select2 form-control" id="{$FIELD_NAME}" name="{$FIELD_NAME}" placeholder="{vtranslate('LBL_SELECT_ONE', $QUALIFIED_MODULE_NAME)}"> + <option></option> + {assign var=PICKLIST_VALUES value=$FIELD_MODEL->get('picklistvalues')} + {foreach item=PICKLIST_VALUE key=PICKLIST_KEY from=$PICKLIST_VALUES} + <option value="{$PICKLIST_KEY}" {if $FIELD_VALUE eq $PICKLIST_KEY} selected {/if}> + {vtranslate($PICKLIST_VALUE, $QUALIFIED_MODULE_NAME)} + </option> + {/foreach} + </select> + {else if $FIELD_TYPE == 'radio'} + <input type="radio" name="{$FIELD_NAME}" value='1' id="{$FIELD_NAME}" {if $FIELD_VALUE} checked="checked" {/if} /> {vtranslate('LBL_YES', $QUALIFIED_MODULE_NAME)} + <input type="radio" name="{$FIELD_NAME}" value='0' id="{$FIELD_NAME}" {if !$FIELD_VALUE} checked="checked" {/if}/> {vtranslate('LBL_NO', $QUALIFIED_MODULE_NAME)} + {else if $FIELD_TYPE == 'password'} + <input type="password" id="{$FIELD_NAME}" class="form-control" data-rule-required="true" name="{$FIELD_NAME}" value="{$FIELD_VALUE}" /> + {else if $FIELD_TYPE == 'url'} + <div class="input-group pull-left col-lg-11 col-sm-11 col-xs-11"> + <input type="text" id="{$FIELD_NAME}" class="form-control" data-rule-required="true" readonly="readonly" name="{$FIELD_NAME}" value="{$FIELD_VALUE}" /> + <span class="input-group-addon cursorPointer"><i class="fa fa-clipboard copyToClipboard"></i></span> + </div> + {if $FIELD_MODEL->get('helpText')} + <i class="fa fa-info-circle" data-toggle="tooltip" title="{$FIELD_MODEL->get('helpText')}" style="margin-top: 8px;"></i> + {/if} + {else} + <input type="text" name="{$FIELD_NAME}" id="{$FIELD_NAME}" class="form-control" {if $FIELD_NAME == 'username'} {/if} value="{$FIELD_VALUE}" /> + {/if} + </div> + </div> + </div> + {/foreach} +{/strip} diff --git a/pkg/vtiger/modules/SMSNotifier/layouts/v7/modules/Settings/SMSNotifier/resources/List.js b/pkg/vtiger/modules/SMSNotifier/layouts/v7/modules/Settings/SMSNotifier/resources/List.js index a0e691c6fede62b8dc4bd6f9806782f9adf2f634..7a60d7f152a2d57d41408b7ace0fe69b14e64bf2 100644 --- a/pkg/vtiger/modules/SMSNotifier/layouts/v7/modules/Settings/SMSNotifier/resources/List.js +++ b/pkg/vtiger/modules/SMSNotifier/layouts/v7/modules/Settings/SMSNotifier/resources/List.js @@ -42,6 +42,7 @@ Settings_Vtiger_List_Js("Settings_SMSNotifier_List_Js", { thisInstance.registerProviderTypeChangeEvent(form); thisInstance.registerPhoneFormatPop(form); thisInstance.registerSaveConfiguration(form); + thisInstance.copyToClipboard(form); } var params = {}; params.cb = callback; @@ -55,6 +56,7 @@ Settings_Vtiger_List_Js("Settings_SMSNotifier_List_Js", { * Function to register change event for SMS server Provider Type */ registerProviderTypeChangeEvent: function (form) { + var thisInstance = this; form.find('.providerType').change(function (e) { var currentTarget = jQuery(e.currentTarget); var selectedProviderName = currentTarget.val(); @@ -71,6 +73,7 @@ Settings_Vtiger_List_Js("Settings_SMSNotifier_List_Js", { if (jQuery(data).find('select').hasClass('select2')) { vtUtils.applyFieldElementsView(jQuery('#provider')); } + thisInstance.copyToClipboard(form); }); }); @@ -114,6 +117,20 @@ Settings_Vtiger_List_Js("Settings_SMSNotifier_List_Js", { }); }); }, + + copyToClipboard : function(form) { + if(jQuery('.copyToClipboard', form).length > 0) { + jQuery('.copyToClipboard', form).on('click', function(e){ + var currentTarget = jQuery(e.currentTarget); + currentTarget.closest('.input-group').find('input').select(); + var success = document.execCommand("copy"); + if(success) { + app.helper.showSuccessNotification({message : app.vtranslate('JS_COPIED_SUCCESSFULLY')}); + } + }); + } + }, + /** * Function to register all the events */ diff --git a/pkg/vtiger/modules/SMSNotifier/modules/SMSNotifier/callbacks/ClickATellNew.php b/pkg/vtiger/modules/SMSNotifier/modules/SMSNotifier/callbacks/ClickATellNew.php new file mode 100755 index 0000000000000000000000000000000000000000..f321ed20f3bf6d3d6ae74472e3f447a340c66ee7 --- /dev/null +++ b/pkg/vtiger/modules/SMSNotifier/modules/SMSNotifier/callbacks/ClickATellNew.php @@ -0,0 +1,27 @@ +<?php +/*+*********************************************************************************** + * The contents of this file are subject to the vtiger CRM Public License Version 1.0 + * ("License"); You may not use this file except in compliance with the License + * The Original Code is: vtiger CRM Open Source + * The Initial Developer of the Original Code is vtiger. + * Portions created by vtiger are Copyright (C) vtiger. + * All Rights Reserved. + *************************************************************************************/ +chdir(dirname(__FILE__) . '/../../../'); +include_once 'includes/main/WebUI.php'; +vimport('includes.http.Request'); + +class SMSNotifier_ClickATellNew_Callbacks { + + function process(Vtiger_Request $request) { + if(vtlib_isModuleActive('SMSNotifier')) { + $providerModel = SMSNotifier_Provider_Model::getInstance('ClickATellNew'); + if($providerModel->validateRequest($request)) { + $providerModel->updateMessageStatus($request); + } + } + } +} + +$clickATell = new SMSNotifier_ClickATellNew_Callbacks(); +$clickATell->process(new Vtiger_Request($_REQUEST)); \ No newline at end of file diff --git a/pkg/vtiger/modules/SMSNotifier/modules/SMSNotifier/providers/ClickATellNew.php b/pkg/vtiger/modules/SMSNotifier/modules/SMSNotifier/providers/ClickATellNew.php new file mode 100755 index 0000000000000000000000000000000000000000..826e096ee1af03b37332d0b94b288525321e5da3 --- /dev/null +++ b/pkg/vtiger/modules/SMSNotifier/modules/SMSNotifier/providers/ClickATellNew.php @@ -0,0 +1,197 @@ +<?php +/*+*********************************************************************************** + * The contents of this file are subject to the vtiger CRM Public License Version 1.0 + * ("License"); You may not use this file except in compliance with the License + * The Original Code is: vtiger CRM Open Source + * The Initial Developer of the Original Code is vtiger. + * Portions created by vtiger are Copyright (C) vtiger. + * All Rights Reserved. + *************************************************************************************/ + +class SMSNotifier_ClickATellNew_Provider implements SMSNotifier_ISMSProvider_Model { + + private $parameters = array(); + private static $SKIPPED_PARAMS = array('callback'); + private $API_URI = 'https://platform.clickatell.com/messages'; + private static $REQUIRED_PARAMETERS = array(array('name'=>'callback','label'=>'Enable delivery notifications URL','type'=>'url'),array('name'=>'api_key','label'=>'API Key','type'=>'text')); + + + /** + * Function to get provider name + * @return <String> provider name + */ + public function getName() { + return 'ClickATellNew'; + } + + /** + * Function to get required parameters other than (userName, password) + * @return <array> required parameters list + */ + public function getRequiredParams() { + //To set default values + foreach (self::$REQUIRED_PARAMETERS as $index => $parameters) { + switch ($parameters['name']) { + case 'callback' : + $parameters['value'] = $this->generateCallbackURL(); + $parameters['helpText'] = vtranslate('LBL_CLICKATELLNEW_CALLBACKURL_INFO', 'Settings:SMSNotifier'); + break; + } + self::$REQUIRED_PARAMETERS[$index] = $parameters; + } + return self::$REQUIRED_PARAMETERS; + } + + /** + * Function to set authentication parameters + * @param <String> $userName + * @param <String> $password + */ + public function setAuthParameters($userName, $password) { + return false; + } + + /** + * Function to set non-auth parameter. + * @param <String> $key + * @param <String> $value + */ + public function setParameter($key, $value) { + $this->parameters[$key] = $value; + } + + /** + * Function to get parameter value + * @param <String> $key + * @param <String> $defaultValue + * @return <String> value/$default value + */ + public function getParameter($key, $defaultValue = false) { + if(isset($this->parameters[$key])) { + return $this->parameters[$key]; + } + return $defaultValue; + } + + /** + * Function to prepare parameters + * @return <Array> parameters + */ + protected function prepareParameters() { + //Default parameters required by provider + foreach (self::$REQUIRED_PARAMETERS as $key=>$fieldInfo) { + if(in_array($fieldInfo['name'], self::$SKIPPED_PARAMS)) continue; + $params[$fieldInfo['name']] = $this->getParameter($fieldInfo['name']); + } + return $params; + } + + /** + * Function to get service URL to use for a given type + * @param <String> $type like SEND, PING, QUERY + */ + public function getServiceURL($type = false) { + return $this->API_URI; + } + + /** + * Function to handle SMS Send operation + * @param <String> $message + * @param <Mixed> $toNumbers One or Array of numbers + */ + public function send($message, $toNumbers) { + if (!is_array($toNumbers)) { + $toNumbers = array($toNumbers); + } + + $params = $this->prepareParameters(); + $params['text'] = $message; + $params['to'] = implode(',', $toNumbers); + $messageParams = array( + 'content' => $params['text'], + 'to' => $toNumbers, + ); + + $headers = array('Content-Type' => 'application/json', 'Authorization' => $params['api_key']); + $httpClient = new Vtiger_Net_Client($this->getServiceURL()); + $httpClient->setHeaders($headers); + $response = $httpClient->doPost(json_encode($messageParams)); + $decodedResponse = Zend_JSON::decode($response); + $results = array(); + + foreach ($decodedResponse['messages'] as $index => $responseMessage) { + $result = array(); + if ($responseMessage['accepted'] == 1) { + $result['id'] = $responseMessage['apiMessageId']; + $result['to'] = $responseMessage['to']; + $result['status'] = self::MSG_STATUS_PROCESSING; + } else { + $result['error'] = true; + $result['statusmessage'] = $responseMessage['error']; + $result['to'] = $responseMessage['to']; + } + $results[] = $result; + } + + return $results; + } + + /** + * Function to get query for status using messgae id + * @param <Number> $messageId + */ + public function query($messageId) { + $result = array(); + + $messageInfo = $this->getMessageStatus($messageId); + $result['statusmessage'] = $messageInfo['statusmessage']; + $result['status'] = $messageInfo['status']; + $result['needlookup'] = 0; + return $result; + } + + + function generateCallbackURL() { + global $site_URL; + $secret = md5(strtotime(date('Y-m-d H:i:s'))); + $siteUrl = trim($site_URL, '/'); + return $siteUrl."/modules/SMSNotifier/callbacks/ClickATellNew.php?vtsecret=".$secret; + } + + function getMessageStatus($messageId) { + $db = PearDatabase::getInstance(); + $query = "SELECT * FROM vtiger_smsnotifier_status WHERE smsmessageid=?"; + $result = $db->pquery($query, array($messageId)); + + if($db->num_rows($result) > 0) { + return $db->query_result_rowdata($result, 0); + } + return array(); + } + function getProviderEditFieldTemplateName() { + return 'ClickATellNew.tpl'; + } + + function updateMessageStatus(Vtiger_Request $request) { + $messageId = $request->get('messageId'); + $status = $request->get('status'); + $messageDescription = $request->get('statusDescription'); + $db = PearDatabase::getInstance(); + $query = "UPDATE vtiger_smsnotifier_status SET status=?, statusmessage=? WHERE smsmessageid=?"; + $db->pquery($query, array($status, $messageDescription, $messageId)); + } + + function validateRequest($request) { + $db = PearDatabase::getInstance(); + $query = "SELECT id FROM vtiger_smsnotifier_servers WHERE parameters like ? AND providertype=? AND isactive=?"; + $result = $db->pquery($query, array('%'.$request->get('vtsecret').'%', $this->getName(), 1)); + + if($db->num_rows($result) > 0) { + return true; + } + return false; + } + + +} +?> \ No newline at end of file diff --git a/vtlib/Vtiger/Filter.php b/vtlib/Vtiger/Filter.php index 3485a09dae1e20ae6e851934f309bef1ff1be149..217007487a5189cd3e4e37312b1216846a456347 100644 --- a/vtlib/Vtiger/Filter.php +++ b/vtlib/Vtiger/Filter.php @@ -47,8 +47,8 @@ class Vtiger_Filter { * @access private */ function initialize($valuemap, $moduleInstance=false) { - $this->id = $valuemap[cvid]; - $this->name= $valuemap[viewname]; + $this->id = $valuemap['cvid']; + $this->name= $valuemap['viewname']; $this->module=$moduleInstance? $moduleInstance: Vtiger_Module::getInstance($valuemap[tabid]); } diff --git a/vtlib/Vtiger/Menu.php b/vtlib/Vtiger/Menu.php index 1f93970927a5b4d7f4828094b063322e266aad3a..d447e5ac1bd79d834b9b9f1b038636124285d507 100644 --- a/vtlib/Vtiger/Menu.php +++ b/vtlib/Vtiger/Menu.php @@ -32,10 +32,10 @@ class Vtiger_Menu { * @access private */ function initialize($valuemap) { - $this->id = $valuemap[parenttabid]; - $this->label = $valuemap[parenttab_label]; - $this->sequence = $valuemap[sequence]; - $this->visible = $valuemap[visible]; + $this->id = $valuemap['parenttabid']; + $this->label = $valuemap['parenttab_label']; + $this->sequence = $valuemap['sequence']; + $this->visible = $valuemap['visible']; } /**