FIX unprivileged user can attach agenda with leave.

This commit is contained in:
Laurent Destailleur 2021-09-19 00:50:23 +02:00
parent 4253b564ba
commit 96436cac3d
15 changed files with 155 additions and 31 deletions

View File

@ -2053,7 +2053,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
// List of actions on element // List of actions on element
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
$formactions = new FormActions($db); $formactions = new FormActions($db);
$somethingshown = $formactions->showactions($object, 'member', $socid, 1, 'listactions', $MAX, '', $morehtmlright); $somethingshown = $formactions->showactions($object, $object->element, $socid, 1, 'listactions', $MAX, '', $morehtmlright);
print '</div></div></div>'; print '</div></div></div>';
} }

View File

@ -394,7 +394,7 @@ if ($rowid && $action != 'edit') {
/* /*
include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php';
$formactions = new FormActions($db); $formactions = new FormActions($db);
$somethingshown = $formactions->showactions($object, 'invoice', $socid, 1); $somethingshown = $formactions->showactions($object, $object->element, $socid, 1);
*/ */
print '</div></div></div>'; print '</div></div></div>';

View File

@ -102,7 +102,7 @@ if (empty($reshook)) {
if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
$backtopage = $backurlforlist; $backtopage = $backurlforlist;
} else { } else {
$backtopage = DOL_URL_ROOT.'/compta/bank/card.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__'); $backtopage = DOL_URL_ROOT.'/asset/card.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
} }
} }
} }
@ -334,7 +334,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
// List of actions on element // List of actions on element
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
$formactions = new FormActions($db); $formactions = new FormActions($db);
$somethingshown = $formactions->showactions($object, 'asset', $socid, 1, '', $MAXEVENT, '', $morehtmlright); $somethingshown = $formactions->showactions($object, $object->element, $socid, 1, '', $MAXEVENT, '', $morehtmlright);
print '</div></div></div>'; print '</div></div></div>';
} }

View File

@ -57,6 +57,7 @@ class Asset extends CommonObject
const STATUS_DRAFT = 0; const STATUS_DRAFT = 0;
const STATUS_VALIDATED = 1; const STATUS_VALIDATED = 1;
const STATUS_CANCELED = 9;
/** /**
@ -95,7 +96,7 @@ class Asset extends CommonObject
'fk_user_creat' => array('type'=>'integer', 'label'=>'UserAuthor', 'visible'=>-2, 'enabled'=>1, 'position'=>510, 'notnull'=>1,), 'fk_user_creat' => array('type'=>'integer', 'label'=>'UserAuthor', 'visible'=>-2, 'enabled'=>1, 'position'=>510, 'notnull'=>1,),
'fk_user_modif' => array('type'=>'integer', 'label'=>'UserModif', 'visible'=>-2, 'enabled'=>1, 'position'=>511, 'notnull'=>-1,), 'fk_user_modif' => array('type'=>'integer', 'label'=>'UserModif', 'visible'=>-2, 'enabled'=>1, 'position'=>511, 'notnull'=>-1,),
'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'visible'=>-2, 'enabled'=>1, 'position'=>1000, 'notnull'=>-1,), 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'visible'=>-2, 'enabled'=>1, 'position'=>1000, 'notnull'=>-1,),
'status' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>1000, 'notnull'=>1, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Active', '-1'=>'Cancel')), 'status' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>1000, 'notnull'=>1, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Active', '9'=>'Cancel')),
); );
/** /**

View File

@ -694,7 +694,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
// List of actions on element // List of actions on element
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
$formactions = new FormActions($db); $formactions = new FormActions($db);
$somethingshown = $formactions->showactions($object, 'bom', $socid, 1, '', $MAXEVENT, '', $morehtmlright); $somethingshown = $formactions->showactions($object, $object->element, $socid, 1, '', $MAXEVENT, '', $morehtmlright);
print '</div></div></div>'; print '</div></div></div>';
} }

View File

@ -278,8 +278,20 @@ if (empty($reshook) && $action == 'add') {
$object->fulldayevent = (!empty($fulldayevent) ? 1 : 0); $object->fulldayevent = (!empty($fulldayevent) ? 1 : 0);
$object->location = GETPOST("location", 'alphanohtml'); $object->location = GETPOST("location", 'alphanohtml');
$object->label = GETPOST('label', 'alphanohtml'); $object->label = GETPOST('label', 'alphanohtml');
$object->fk_element = GETPOST("fk_element", 'int');
$object->elementtype = GETPOST("elementtype", 'alpha'); if (GETPOST("elementtype", 'alpha')) {
$modulecodetouseforpermissioncheck = GETPOST("elementtype", 'alpha');
$hasPermissionOnLinkedObject = 0;
if ($user->hasRight($modulecodetouseforpermissioncheck, 'read')) {
$hasPermissionOnLinkedObject = 1;
}
if ($hasPermissionOnLinkedObject) {
$object->fk_element = GETPOST("fk_element", 'int');
$object->elementtype = GETPOST("elementtype", 'alpha');
}
}
if (!GETPOST('label')) { if (!GETPOST('label')) {
if (GETPOST('actioncode', 'aZ09') == 'AC_RDV' && $contact->getFullName($langs)) { if (GETPOST('actioncode', 'aZ09') == 'AC_RDV' && $contact->getFullName($langs)) {
$object->label = $langs->transnoentitiesnoconv("TaskRDVWith", $contact->getFullName($langs)); $object->label = $langs->transnoentitiesnoconv("TaskRDVWith", $contact->getFullName($langs));
@ -520,8 +532,20 @@ if (empty($reshook) && $action == 'update') {
} }
$object->fk_project = GETPOST("projectid", 'int'); $object->fk_project = GETPOST("projectid", 'int');
$object->note_private = trim(GETPOST("note", "restricthtml")); $object->note_private = trim(GETPOST("note", "restricthtml"));
$object->fk_element = GETPOST("fk_element", "int");
$object->elementtype = GETPOST("elementtype", "alphanohtml"); if (GETPOST("elementtype", 'alpha')) {
$modulecodetouseforpermissioncheck = GETPOST("elementtype", 'alpha');
$hasPermissionOnLinkedObject = 0;
if ($user->hasRight($modulecodetouseforpermissioncheck, 'read')) {
$hasPermissionOnLinkedObject = 1;
}
if ($hasPermissionOnLinkedObject) {
$object->fk_element = GETPOST("fk_element", 'int');
$object->elementtype = GETPOST("elementtype", 'alpha');
}
}
if (!$datef && $percentage == 100) { if (!$datef && $percentage == 100) {
$error++; $donotclearsession = 1; $error++; $donotclearsession = 1;
setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateEnd")), $object->errors, 'errors'); setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateEnd")), $object->errors, 'errors');
@ -1191,7 +1215,7 @@ if ($action == 'create') {
print img_picto('', 'project', 'class="pictofixedwidth"'); print img_picto('', 'project', 'class="pictofixedwidth"');
print $formproject->select_projects((empty($societe->id) ? '' : $societe->id), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx'); print $formproject->select_projects((empty($societe->id) ? '' : $societe->id), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx');
print '&nbsp;<a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.(empty($societe->id) ? '' : $societe->id).'&action=create&amp;backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create').'">'; print '&nbsp;<a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.(empty($societe->id) ? '' : $societe->id).'&action=create&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create').'">';
print '<span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddProject").'"></span></a>'; print '<span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddProject").'"></span></a>';
$urloption = '?action=create&donotclearsession=1'; $urloption = '?action=create&donotclearsession=1';
$url = dol_buildpath('comm/action/card.php', 2).$urloption; $url = dol_buildpath('comm/action/card.php', 2).$urloption;
@ -1218,7 +1242,7 @@ if ($action == 'create') {
if (!empty($projectid)) { if (!empty($projectid)) {
$projectsListId = $projectid; $projectsListId = $projectid;
} }
$tid = GETPOST("projecttaskid") ? GETPOST("projecttaskid") : ''; $tid = GETPOSTISSET("projecttaskid") ? GETPOST("projecttaskid", 'int') : (GETPOSTISSET("taskid") ? GETPOST("taskid", 'int') : '');
$formproject->selectTasks((!empty($societe->id) ? $societe->id : -1), $tid, 'taskid', 24, 0, '1', 1, 0, 0, 'maxwidth500', $projectsListId); $formproject->selectTasks((!empty($societe->id) ? $societe->id : -1), $tid, 'taskid', 24, 0, '1', 1, 0, 0, 'maxwidth500', $projectsListId);
print '</td></tr>'; print '</td></tr>';
} }
@ -1226,12 +1250,28 @@ if ($action == 'create') {
// Object linked // Object linked
if (!empty($origin) && !empty($originid)) { if (!empty($origin) && !empty($originid)) {
include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
print '<tr><td class="titlefieldcreate">'.$langs->trans("LinkedObject").'</td>';
print '<td colspan="3">'.dolGetElementUrl($originid, $origin, 1).'</td></tr>'; $hasPermissionOnLinkedObject = 0;
print '<input type="hidden" name="fk_element" value="'.GETPOST('originid', 'int').'">'; if ($user->hasRight($origin, 'read')) {
print '<input type="hidden" name="elementtype" value="'.GETPOST('origin').'">'; $hasPermissionOnLinkedObject = 1;
print '<input type="hidden" name="originid" value="'.GETPOST('originid', 'int').'">'; }
print '<input type="hidden" name="origin" value="'.GETPOST('origin').'">'; //var_dump('origin='.$origin.' originid='.$originid.' $hasPermissionOnLinkedObject='.$hasPermissionOnLinkedObject);
if (! in_array($origin, array('societe', 'project', 'task', 'user'))) {
// We do not use link for object that already contains a hard coded field to make links with agenda events
print '<tr><td class="titlefieldcreate">'.$langs->trans("LinkedObject").'</td>';
print '<td colspan="3">';
if ($hasPermissionOnLinkedObject) {
print dolGetElementUrl($originid, $origin, 1);
print '<input type="hidden" name="fk_element" value="'.$originid.'">';
print '<input type="hidden" name="elementtype" value="'.$origin.'">';
print '<input type="hidden" name="originid" value="'.$originid.'">';
print '<input type="hidden" name="origin" value="'.$origin.'">';
} else {
print '<!-- no permission on object to link '.$origin.' id '.$originid.' -->';
}
print '</td></tr>';
}
} }
$reg = array(); $reg = array();

View File

@ -131,8 +131,8 @@ if ($action == 'add' && !empty($permissiontoadd)) {
$result = $object->create($user); $result = $object->create($user);
if ($result > 0) { if ($result > 0) {
// Creation OK // Creation OK
if ($conf->categorie->enabled) { if ($conf->categorie->enabled && method_exists($object, 'setCategories')) {
$categories = GETPOST('categories', 'array'); $categories = GETPOST('categories', 'array:int');
$object->setCategories($categories); $object->setCategories($categories);
} }
$urltogo = $backtopage ? str_replace('__ID__', $result, $backtopage) : $backurlforlist; $urltogo = $backtopage ? str_replace('__ID__', $result, $backtopage) : $backurlforlist;

View File

@ -221,10 +221,13 @@ class FormActions
if ($typeelement == 'project') { if ($typeelement == 'project') {
$projectid = $object->id; $projectid = $object->id;
} }
if ($typeelement == 'task') {
$taskid = $object->id;
}
$newcardbutton = ''; $newcardbutton = '';
if (!empty($conf->agenda->enabled) && !empty($user->rights->agenda->myactions->create)) { if (!empty($conf->agenda->enabled) && !empty($user->rights->agenda->myactions->create)) {
$url = DOL_URL_ROOT.'/comm/action/card.php?action=create&amp;datep='.urlencode(dol_print_date(dol_now(), 'dayhourlog', 'tzuser')).'&amp;origin='.urlencode($typeelement).'&amp;originid='.$object->id.((!empty($object->socid) && $object->socid > 0) ? '&amp;socid='.$object->socid : ((!empty($socid) && $socid > 0) ? '&amp;socid='.$socid : '')).($projectid > 0 ? '&amp;projectid='.$projectid : '').'&amp;backtopage='.urlencode($urlbacktopage); $url = DOL_URL_ROOT.'/comm/action/card.php?action=create&amp;datep='.urlencode(dol_print_date(dol_now(), 'dayhourlog', 'tzuser')).'&amp;origin='.urlencode($typeelement).'&amp;originid='.$object->id.((!empty($object->socid) && $object->socid > 0) ? '&amp;socid='.$object->socid : ((!empty($socid) && $socid > 0) ? '&amp;socid='.$socid : '')).($projectid > 0 ? '&amp;projectid='.$projectid : '').($taskid > 0 ? '&amp;taskid='.$taskid : '').'&amp;backtopage='.urlencode($urlbacktopage);
$newcardbutton .= dolGetButtonTitle($langs->trans("AddEvent"), '', 'fa fa-plus-circle', $url); $newcardbutton .= dolGetButtonTitle($langs->trans("AddEvent"), '', 'fa fa-plus-circle', $url);
} }

View File

@ -2166,6 +2166,9 @@ function dolGetElementUrl($objectid, $objecttype, $withpicto = 0, $option = '')
$classpath = 'fichinter/class'; $classpath = 'fichinter/class';
$module = 'ficheinter'; $module = 'ficheinter';
$myobject = 'fichinter'; $myobject = 'fichinter';
} elseif ($objecttype == 'project') {
$classpath = 'projet/class';
$module = 'projet';
} elseif ($objecttype == 'task') { } elseif ($objecttype == 'task') {
$classpath = 'projet/class'; $classpath = 'projet/class';
$module = 'projet'; $module = 'projet';

View File

@ -699,7 +699,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
// List of actions on element // List of actions on element
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
$formactions = new FormActions($db); $formactions = new FormActions($db);
$somethingshown = $formactions->showactions($object, 'mo', $socid, 1, '', $MAXEVENT, '', $morehtmlright); $somethingshown = $formactions->showactions($object, $object->element, $socid, 1, '', $MAXEVENT, '', $morehtmlright);
print '</div></div></div>'; print '</div></div></div>';
} }

View File

@ -643,14 +643,14 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
$MAXEVENT = 10; $MAXEVENT = 10;
$morehtmlright = '<a href="'.dol_buildpath('/partnership/partnership_agenda.php', 1).'?id='.$object->id.'">'; $morehtmlright = '<a href="'.DOL_URL_ROOT.'/partnership/partnership_agenda.php?id='.$object->id.'">';
$morehtmlright .= $langs->trans("SeeAll"); $morehtmlright .= $langs->trans("SeeAll");
$morehtmlright .= '</a>'; $morehtmlright .= '</a>';
// List of actions on element // List of actions on element
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
$formactions = new FormActions($db); $formactions = new FormActions($db);
$somethingshown = $formactions->showactions($object, $object->element.'@'.$object->module, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlright); $somethingshown = $formactions->showactions($object, $object->element, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlright);
print '</div></div></div>'; print '</div></div></div>';
} }

View File

@ -462,7 +462,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
// List of actions on element // List of actions on element
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
$formactions = new FormActions($db); $formactions = new FormActions($db);
$somethingshown = $formactions->showactions($object, 'inventory', 0, 1, '', $MAXEVENT, '', $morehtmlright); $somethingshown = $formactions->showactions($object, $object->element, 0, 1, '', $MAXEVENT, '', $morehtmlright);
print '</div></div></div>'; print '</div></div></div>';
} }

View File

@ -36,7 +36,7 @@ class mod_recruitmentcandidature_standard extends ModeleNumRefRecruitmentCandida
*/ */
public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr'
public $prefix = 'JOC'; public $prefix = 'JOA';
/** /**
* @var string Error code (or message) * @var string Error code (or message)

View File

@ -663,26 +663,103 @@ class User extends CommonObject
* You can use it like this: if ($user->hasRight('module', 'level11')). * You can use it like this: if ($user->hasRight('module', 'level11')).
* It replaces old syntax: if ($user->rights->module->level1) * It replaces old syntax: if ($user->rights->module->level1)
* *
* @param int $module Id of permission to add or 0 to add several permissions * @param int $module Module of permission to check
* @param string $permlevel1 Permission level1 * @param string $permlevel1 Permission level1 (Example: 'read', 'write', 'delete')
* @param string $permlevel2 Permission level2 * @param string $permlevel2 Permission level2
* @return int 1 if user has permission, 0 if not. * @return int 1 if user has permission, 0 if not.
* @see clearrights(), delrights(), getrights(), hasRight() * @see clearrights(), delrights(), getrights(), hasRight()
*/ */
public function hasRight($module, $permlevel1, $permlevel2 = '') public function hasRight($module, $permlevel1, $permlevel2 = '')
{ {
global $conf;
// For compatibility with bad naming permissions on module
$moduletomoduletouse = array(
'contract' => 'contrat',
'member' => 'adherent', // We must check $user->rights->adherent...
'mo' => 'mrp',
'order' => 'commande',
'product' => 'produit', // We must check $user->rights->produit...
'project' => 'projet',
'shipping' => 'expedition',
'task' => 'task@projet',
'fichinter' => 'ficheinter',
'invoice' => 'facture',
'invoice_supplier' => 'fournisseur',
'knowledgerecord' => 'knowledgerecord@knowledgemanagement'
);
if (!empty($moduletomoduletouse[$module])) {
$module = $moduletomoduletouse[$module];
}
// If module is abc@module, we check permission user->rights->module->abc->permlevel1
$tmp = explode('@', $module, 2);
if (! empty($tmp[1])) {
$module = $tmp[1];
$permlevel2 = $permlevel1;
$permlevel1 = $tmp[0];
}
//var_dump($module);
//var_dump($this->rights->$module);
if (!in_array($module, $conf->modules)) {
return 0;
}
// For compatibility with bad naming permissions on permlevel1
if ($permlevel1 == 'propale') {
$permlevel1 = 'propal';
}
if ($permlevel1 == 'member') {
$permlevel1 = 'adherent';
}
if ($permlevel1 == 'recruitmentcandidature') {
$permlevel1 = 'recruitmentjobposition';
}
//var_dump($module.' '.$permlevel1.' '.$permlevel2);
if (empty($module) || empty($this->rights) || empty($this->rights->$module) || empty($permlevel1)) { if (empty($module) || empty($this->rights) || empty($this->rights->$module) || empty($permlevel1)) {
return 0; return 0;
} }
if ($permlevel2) { if ($permlevel2) {
if (!empty($this->rights->$module->$permlevel1) && !empty($this->rights->$module->$permlevel1->$permlevel2)) { if (!empty($this->rights->$module->$permlevel1)) {
return $this->rights->$module->$permlevel1->$permlevel2; if (!empty($this->rights->$module->$permlevel1->$permlevel2)) {
return $this->rights->$module->$permlevel1->$permlevel2;
}
// For backward compatibility with old permissions called "lire", "creer", "create", "supprimer"
// instead of "read", "write", "delete"
if ($permlevel2 == 'read' && !empty($this->rights->$module->$permlevel1->lire)) {
return $this->rights->$module->lire;
}
if ($permlevel2 == 'write' && !empty($this->rights->$module->$permlevel1->creer)) {
return $this->rights->$module->create;
}
if ($permlevel2 == 'write' && !empty($this->rights->$module->$permlevel1->create)) {
return $this->rights->$module->create;
}
if ($permlevel2 == 'delete' && !empty($this->rights->$module->$permlevel1->supprimer)) {
return $this->rights->$module->supprimer;
}
} }
} else { } else {
if (!empty($this->rights->$module->$permlevel1)) { if (!empty($this->rights->$module->$permlevel1)) {
return $this->rights->$module->$permlevel1; return $this->rights->$module->$permlevel1;
} }
// For backward compatibility with old permissions called "lire", "creer", "create", "supprimer"
// instead of "read", "write", "delete"
if ($permlevel1 == 'read' && !empty($this->rights->$module->lire)) {
return $this->rights->$module->lire;
}
if ($permlevel1 == 'write' && !empty($this->rights->$module->creer)) {
return $this->rights->$module->create;
}
if ($permlevel1 == 'write' && !empty($this->rights->$module->create)) {
return $this->rights->$module->create;
}
if ($permlevel1 == 'delete' && !empty($this->rights->$module->supprimer)) {
return $this->rights->$module->supprimer;
}
} }
return 0; return 0;

View File

@ -344,7 +344,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
// List of actions on element // List of actions on element
include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php';
$formactions = new FormActions($db); $formactions = new FormActions($db);
$somethingshown = $formactions->showactions($object, 'websiteaccount', $socid, 1, '', $MAXEVENT); $somethingshown = $formactions->showactions($object, $object->element, $socid, 1, '', $MAXEVENT);
*/ */
print '</div></div></div>'; print '</div></div></div>';