2 if(!defined('sugarEntry') || !sugarEntry)
3 die('Not A Valid Entry Point');
4 /*********************************************************************************
5 * SugarCRM Community Edition is a customer relationship management program developed by
6 * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU Affero General Public License version 3 as published by the
10 * Free Software Foundation with the addition of the following permission added
11 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
12 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
13 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
20 * You should have received a copy of the GNU Affero General Public License along with
21 * this program; if not, see http://www.gnu.org/licenses or write to the Free
22 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
26 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
28 * The interactive user interfaces in modified source and object code versions
29 * of this program must display Appropriate Legal Notices, as required under
30 * Section 5 of the GNU Affero General Public License version 3.
32 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
33 * these Appropriate Legal Notices must retain the display of the "Powered by
34 * SugarCRM" logo. If the display of the logo is not reasonably feasible for
35 * technical reasons, the Appropriate Legal Notices must display the words
36 * "Powered by SugarCRM".
37 ********************************************************************************/
39 require_once ('include/upload_file.php');
42 // User is used to store Forecast information.
43 class Document extends SugarBean {
55 var $modified_user_id;
56 var $assigned_user_id;
59 var $document_revision_id;
66 var $related_doc_name;
67 var $related_doc_rev_id;
68 var $related_doc_rev_number;
74 var $last_rev_create_date;
75 var $last_rev_created_by;
76 var $last_rev_created_name;
78 var $file_url_noimage;
80 var $table_name = "documents";
81 var $object_name = "Document";
82 var $user_preferences;
84 var $encodeFields = Array ();
86 // This is used to retrieve related fields from form posts.
87 var $additional_column_fields = Array ('revision');
89 var $new_schema = true;
90 var $module_dir = 'Documents';
94 var $relationship_fields = Array(
95 'contract_id'=>'contracts',
100 parent :: SugarBean();
101 $this->setupCustomFields('Documents'); //parameter is module name
102 $this->disable_row_level_security = false;
105 function save($check_notify = false) {
107 if (empty($this->doc_type)) {
108 $this->doc_type = 'Sugar';
110 if (empty($this->id) || $this->new_with_id)
112 if (empty($this->id)) {
113 $this->id = create_guid();
114 $this->new_with_id = true;
117 if ( isset($_REQUEST) && isset($_REQUEST['duplicateSave']) && $_REQUEST['duplicateSave'] == true && isset($_REQUEST['filename_old_doctype']) ) {
118 $this->doc_type = $_REQUEST['filename_old_doctype'];
121 $isDuplicate = false;
124 $Revision = new DocumentRevision();
126 $Revision->in_workflow = true;
127 $Revision->not_use_rel_in_req = true;
128 $Revision->new_rel_id = $this->id;
129 $Revision->new_rel_relname = 'Documents';
130 $Revision->change_log = translate('DEF_CREATE_LOG','Documents');
131 $Revision->revision = $this->revision;
132 $Revision->document_id = $this->id;
133 $Revision->filename = $this->filename;
135 if(isset($this->file_ext))
137 $Revision->file_ext = $this->file_ext;
140 if(isset($this->file_mime_type))
142 $Revision->file_mime_type = $this->file_mime_type;
145 $Revision->doc_type = $this->doc_type;
146 if ( isset($this->doc_id) ) {
147 $Revision->doc_id = $this->doc_id;
149 if ( isset($this->doc_url) ) {
150 $Revision->doc_url = $this->doc_url;
153 $Revision->id = create_guid();
154 $Revision->new_with_id = true;
156 $createRevision = false;
157 //Move file saved during populatefrompost to match the revision id rather than document id
158 if (!empty($_FILES['filename_file'])) {
159 rename("upload://{$this->id}", "upload://{$Revision->id}");
160 $createRevision = true;
161 } else if ( $isDuplicate && ( empty($this->doc_type) || $this->doc_type == 'Sugar' ) ) {
162 // Looks like we need to duplicate a file, this is tricky
163 $oldDocument = new Document();
164 $oldDocument->retrieve($_REQUEST['duplicateId']);
165 $old_name = "upload://{$oldDocument->document_revision_id}";
166 $new_name = "upload://{$Revision->id}";
167 $GLOBALS['log']->debug("Attempting to copy from $old_name to $new_name");
168 copy($old_name, $new_name);
169 $createRevision = true;
172 // For external documents, we just need to make sure we have a doc_id
173 if ( !empty($this->doc_id) && $this->doc_type != 'Sugar' ) {
174 $createRevision = true;
177 if ( $createRevision ) {
179 //update document with latest revision id
180 $this->process_save_dates=false; //make sure that conversion does not happen again.
181 $this->document_revision_id = $Revision->id;
185 //set relationship field values if contract_id is passed (via subpanel create)
186 if (!empty($_POST['contract_id'])) {
187 $save_revision['document_revision_id']=$this->document_revision_id;
188 $this->load_relationship('contracts');
189 $this->contracts->add($_POST['contract_id'],$save_revision);
192 if ((isset($_POST['load_signed_id']) and !empty($_POST['load_signed_id']))) {
193 $query="update linked_documents set deleted=1 where id='".$_POST['load_signed_id']."'";
194 $this->db->query($query);
198 return parent :: save($check_notify);
200 function get_summary_text() {
201 return "$this->document_name";
204 function is_authenticated() {
205 return $this->authenticated;
208 function fill_in_additional_list_fields() {
209 $this->fill_in_additional_detail_fields();
212 function fill_in_additional_detail_fields() {
214 global $current_language;
218 parent::fill_in_additional_detail_fields();
220 $mod_strings = return_module_language($current_language, 'Documents');
222 if (!empty($this->document_revision_id)) {
224 $query = "SELECT users.first_name AS first_name, users.last_name AS last_name, document_revisions.date_entered AS rev_date,
225 document_revisions.filename AS filename, document_revisions.revision AS revision,
226 document_revisions.file_ext AS file_ext, document_revisions.file_mime_type AS file_mime_type
227 FROM users, document_revisions
228 WHERE users.id = document_revisions.created_by AND document_revisions.id = '$this->document_revision_id'";
230 $result = $this->db->query($query);
231 $row = $this->db->fetchByAssoc($result);
234 if(isset($this->document_name))
236 $this->name = $this->document_name;
239 if(isset($row['filename']))$this->filename = $row['filename'];
240 //$this->latest_revision = $row['revision'];
241 if(isset($row['revision']))$this->revision = $row['revision'];
243 //image is selected based on the extension name <ext>_icon_inline, extension is stored in document_revisions.
244 //if file is not found then default image file will be used.
246 global $img_name_bare;
247 if (!empty ($row['file_ext'])) {
248 $img_name = SugarThemeRegistry::current()->getImageURL(strtolower($row['file_ext'])."_image_inline.gif");
249 $img_name_bare = strtolower($row['file_ext'])."_image_inline";
253 //set default file name.
254 if (!empty ($img_name) && file_exists($img_name)) {
255 $img_name = $img_name_bare;
257 $img_name = "def_image_inline"; //todo change the default image.
259 if($this->ACLAccess('DetailView')){
261 $file_url = "<a href='index.php?entryPoint=download&id=".basename(UploadFile :: get_url($this->filename, $this->document_revision_id))."&type=Documents' target='_blank'>".SugarThemeRegistry::current()->getImage($img_name, 'border="0"', null,null,'.gif',$mod_strings['LBL_LIST_VIEW_DOCUMENT'])."</a>";
263 if(!empty($this->doc_type) && $this->doc_type != 'Sugar' && !empty($this->doc_url))
264 $file_url= "<a href='".$this->doc_url."' target='_blank'>".SugarThemeRegistry::current()->getImage($this->doc_type.'_image_inline', 'border="0"',null,null,'.png',$mod_strings['LBL_LIST_VIEW_DOCUMENT'])."</a>";
266 $this->file_url = $file_url;
267 $this->file_url_noimage = "index.php?entryPoint=download&type=Documents&&id={$this->document_revision_id}";
269 $this->file_url = "";
270 $this->file_url_noimage = "";
273 //get last_rev_by user name.
275 $this->last_rev_created_name = $locale->getLocaleFormattedName($row['first_name'], $row['last_name']);
277 $this->last_rev_create_date = $timedate->to_display_date_time($this->db->fromConvert($row['rev_date'], 'datetime'));
278 $this->last_rev_mime_type = $row['file_mime_type'];
281 global $app_list_strings;
282 if(!empty($this->status_id)) {
283 //_pp($this->status_id);
284 $this->status = $app_list_strings['document_status_dom'][$this->status_id];
286 if (!empty($this->related_doc_id)) {
287 $this->related_doc_name = Document::get_document_name($this->related_doc_id);
288 $this->related_doc_rev_number = DocumentRevision::get_document_revision_name($this->related_doc_rev_id);
290 $this->save_file = basename($this->file_url_noimage);
294 function list_view_parse_additional_sections(& $list_form, $xTemplateSection) {
298 function create_export_query(&$order_by, &$where, $relate_link_join='')
300 $custom_join = $this->custom_fields->getJOIN(true, true,$where);
302 $custom_join['join'] .= $relate_link_join;
306 $query .= $custom_join['select'];
308 $query .= " FROM documents ";
310 $query .= $custom_join['join'];
313 $where_auto = " documents.deleted = 0";
316 $query .= " WHERE $where AND ".$where_auto;
318 $query .= " WHERE ".$where_auto;
321 $query .= " ORDER BY $order_by";
323 $query .= " ORDER BY documents.document_name";
328 function get_list_view_data() {
329 global $current_language;
330 $app_list_strings = return_app_list_strings_language($current_language);
332 $document_fields = $this->get_list_view_array();
334 $this->fill_in_additional_list_fields();
337 $document_fields['FILENAME'] = $this->filename;
338 $document_fields['FILE_URL'] = $this->file_url;
339 $document_fields['FILE_URL_NOIMAGE'] = $this->file_url_noimage;
340 $document_fields['LAST_REV_CREATED_BY'] = $this->last_rev_created_name;
341 $document_fields['CATEGORY_ID'] = empty ($this->category_id) ? "" : $app_list_strings['document_category_dom'][$this->category_id];
342 $document_fields['SUBCATEGORY_ID'] = empty ($this->subcategory_id) ? "" : $app_list_strings['document_subcategory_dom'][$this->subcategory_id];
343 $document_fields['NAME'] = $this->document_name;
344 $document_fields['DOCUMENT_NAME_JAVASCRIPT'] = $GLOBALS['db']->quote($document_fields['DOCUMENT_NAME']);
345 return $document_fields;
347 function mark_relationships_deleted($id) {
348 //do nothing, this call is here to avoid default delete processing since
349 //delete.php handles deletion of document revisions.
352 function bean_implements($interface) {
353 switch ($interface) {
361 function get_document_name($doc_id){
362 if (empty($doc_id)) return null;
364 $db = DBManagerFactory::getInstance();
365 $query="select document_name from documents where id='$doc_id'";
366 $result=$db->query($query);
367 if (!empty($result)) {
368 $row=$db->fetchByAssoc($result);
370 return $row['document_name'];
377 require_once('modules/Documents/DocumentExternalApiDropDown.php');