Example #1
0
 public function handle($onSuccess, $onFailure, Request $request, User $user, Calendar $calendar = null)
 {
     $new = false;
     if (is_null($calendar)) {
         $calendar = new Calendar();
         $calendar->setPrincipaluri($user->getIdentityPrincipal()->getUri());
         $calendar->setUri(UUIDUtil::getUUID());
         $new = true;
     }
     $form = $this->formfactory->create(new CalendarType(), $calendar);
     $form->handleRequest($request);
     if ($form->isValid()) {
         $this->em->persist($calendar);
         $this->em->flush();
         return $onSuccess($form, $calendar, $new);
     }
     return $onFailure($form, $calendar, $new);
 }
Example #2
0
 public function handle($onSuccess, $onFailure, Request $request, User $user, Addressbook $addressbook = null)
 {
     $new = false;
     if (is_null($addressbook)) {
         $addressbook = new Addressbook();
         $addressbook->setPrincipaluri($user->getIdentityPrincipal()->getUri());
         $addressbook->setUri(UUIDUtil::getUUID());
         $addressbook->setSynctoken('1');
         $new = true;
     }
     $form = $this->formfactory->create(new AddressbookType(), $addressbook);
     $form->handleRequest($request);
     if ($form->isValid()) {
         $this->em->persist($addressbook);
         $this->em->flush();
         return $onSuccess($form, $addressbook, $new);
     }
     return $onFailure($form, $addressbook, $new);
 }
Example #3
0
	/**
	 * @return string
	 */
	public function GenerateStrId()
	{
		return \Sabre\DAV\UUIDUtil::getUUID().'.vcf';
	}
Example #4
0
 /**
  * Returns a list of calendars for a principal.
  *
  * Every project is an array with the following keys:
  *  * id, a unique id that will be used by other functions to modify the
  *    calendar. This can be the same as the uri or a database key.
  *  * uri, which the basename of the uri with which the calendar is
  *    accessed.
  *  * principaluri. The owner of the calendar. Almost always the same as
  *    principalUri passed to this method.
  *
  * Furthermore it can contain webdav properties in clark notation. A very
  * common one is '{DAV:}displayname'.
  * 
  * MODIFIED: THIS METHOD NOW NEEDS TO BE ABLE TO RETRIEVE SHARED CALENDARS
  *
  * @param string $principalUri
  * @return array
  */
 public function getCalendarsForUser($principalUri)
 {
     $aCalendars = $this->getOwnCalendarsForUser($principalUri);
     if (count($aCalendars) === 0) {
         $this->createCalendar($principalUri, \Sabre\DAV\UUIDUtil::getUUID(), ['{DAV:}displayname' => \CApi::ClientI18N('CALENDAR/CALENDAR_DEFAULT_NAME', basename($principalUri)), '{' . \Sabre\CalDAV\Plugin::NS_CALENDARSERVER . '}getctag' => 1, '{' . \Sabre\CalDAV\Plugin::NS_CALDAV . '}calendar-description' => '', '{http://apple.com/ns/ical/}calendar-color' => \Afterlogic\DAV\Constants::CALENDAR_DEFAULT_COLOR, '{http://apple.com/ns/ical/}calendar-order' => 0]);
         $aCalendars = $this->getOwnCalendarsForUser($principalUri);
     }
     /*		
     		$aSharedCalendars = $this->getSharedCalendarsForUser($principalUri);
     		$aSharedToAllCalendars = $this->getSharedCalendarsForUser(
     				\Afterlogic\DAV\Utils::getTenantPrincipalUri($principalUri)
     		);
     		
     		foreach ($aSharedToAllCalendars as $iKey => $aSharedToAllCalendar) {
     			
     			if (isset($aCalendars[$iKey])) {
     				
     				$aSharedToAllCalendar['{http://sabredav.org/ns}read-only'] = false;
     			}
     			$aCalendars[$iKey] = $aSharedToAllCalendar;
     		}
     		foreach ($aSharedCalendars as $iKey => $aSharedCalendar) {
     			
     			if (isset($aCalendars[$iKey])) {
     				
     				$aSharedCalendar['{http://sabredav.org/ns}read-only'] = false;
     			}
     			$aCalendars[$iKey] = $aSharedCalendar;
     		}
     */
     $aSharedCalendars = array();
     return array_merge($aCalendars, $aSharedCalendars);
 }
Example #5
0
 /**
  * @param \CAccount $oAccount
  * @return string
  */
 public function generateXMLProfile($oAccount)
 {
     $mResult = false;
     if ($oAccount) {
         $oDomImplementation = new DOMImplementation();
         $oDocumentType = $oDomImplementation->createDocumentType('plist', '-//Apple//DTD PLIST 1.0//EN', 'http://www.apple.com/DTDs/PropertyList-1.0.dtd');
         $oXmlDocument = $oDomImplementation->createDocument('', '', $oDocumentType);
         $oXmlDocument->xmlVersion = '1.0';
         $oXmlDocument->encoding = 'UTF-8';
         $oXmlDocument->formatOutput = true;
         $oPlist = $oXmlDocument->createElement('plist');
         $oPlist->setAttribute('version', '1.0');
         $sPayloadId = $this->oApiDavManager ? 'afterlogic.' . $this->oApiDavManager->getServerHost($oAccount) : '';
         $aPayload = array('PayloadVersion' => 1, 'PayloadUUID' => \Sabre\DAV\UUIDUtil::getUUID(), 'PayloadType' => 'Configuration', 'PayloadRemovalDisallowed' => false, 'PayloadIdentifier' => $sPayloadId, 'PayloadOrganization' => $oAccount->Domain->SiteName, 'PayloadDescription' => $oAccount->Domain->SiteName . ' Mobile', 'PayloadDisplayName' => $oAccount->Domain->SiteName . ' Mobile Profile');
         $oArrayElement = $oXmlDocument->createElement('array');
         $bIsDemo = false;
         \CApi::Plugin()->RunHook('plugin-is-demo-account', array(&$oAccount, &$bIsDemo));
         if (!$bIsDemo) {
             $aInfo = $this->oApiUsersManager->getUserAccounts($oAccount->IdUser);
             if (is_array($aInfo) && 0 < count($aInfo)) {
                 foreach (array_keys($aInfo) as $iIdAccount) {
                     if ($oAccount->IdAccount === $iIdAccount) {
                         $oAccountItem = $oAccount;
                     } else {
                         $oAccountItem = $this->oApiUsersManager->getAccountById($iIdAccount);
                     }
                     $oEmailDictElement = $this->_generateEmailDict($oXmlDocument, $sPayloadId, $oAccountItem, $bIsDemo);
                     if ($oEmailDictElement === false) {
                         return false;
                     } else {
                         $oArrayElement->appendChild($oEmailDictElement);
                     }
                     unset($oAccountItem);
                     unset($oEmailDictElement);
                 }
             } else {
                 return false;
             }
         }
         // Calendars
         $oCaldavDictElement = $this->_generateCaldavDict($oXmlDocument, $sPayloadId, $oAccount, $bIsDemo);
         $oArrayElement->appendChild($oCaldavDictElement);
         // Contacts
         $oCarddavDictElement = $this->_generateCarddavDict($oXmlDocument, $sPayloadId, $oAccount, $bIsDemo);
         $oArrayElement->appendChild($oCarddavDictElement);
         $oDictElement = $this->_generateDict($oXmlDocument, $aPayload);
         $oPayloadContentElement = $oXmlDocument->createElement('key', 'PayloadContent');
         $oDictElement->appendChild($oPayloadContentElement);
         $oDictElement->appendChild($oArrayElement);
         $oPlist->appendChild($oDictElement);
         $oXmlDocument->appendChild($oPlist);
         $mResult = $oXmlDocument->saveXML();
     }
     return $mResult;
 }
Example #6
0
 /**
  * @param CContact $oContact
  * @return bool
  */
 public function createContact($oContact)
 {
     $bResult = false;
     if (isset($oContact)) {
         $this->init($oContact->IdUser);
         $sUUID = \Sabre\DAV\UUIDUtil::getUUID();
         if (empty($oContact->IdContact)) {
             $oContact->IdContact = $sUUID;
         }
         $vCard = new \Sabre\VObject\Component('VCARD');
         CApiContactsVCardHelper::UpdateVCardFromContact($oContact, $vCard);
         $sUrl = $this->AddressBookHomeSet . \afterlogic\DAV\Constants::ADDRESSBOOK_DEFAULT_NAME . '/' . $oContact->IdContact . '.vcf';
         $this->Dav->CreateItem($sUrl, $vCard->serialize());
         $bResult = true;
         /*
         			$oContact->initBeforeChange();
         			$sEmail = $oContact->ViewEmail;
         			$oAddressBook = $this->getAddressBook($oContact->IdUser, 'Collected');
         			$aContactsIds = $this->searchContactItemsByEmail($oContact->IdUser, $sEmail, $oAddressBook);
         
         			$this->deleteContactsByAddressBook($oContact->IdUser, $aContactsIds, $oAddressBook);
         */
     }
     return $bResult;
 }
Example #7
0
 /**
  * Checks if the submitted iCalendar data is in fact, valid.
  *
  * An exception is thrown if it's not.
  *
  * @param resource|string $data
  * @return void
  */
 protected function validateVCard(&$data)
 {
     // If it's a stream, we convert it to a string first.
     if (is_resource($data)) {
         $data = stream_get_contents($data);
     }
     // Converting the data to unicode, if needed.
     $data = DAV\StringUtil::ensureUTF8($data);
     try {
         $vobj = VObject\Reader::read($data);
     } catch (VObject\ParseException $e) {
         throw new DAV\Exception\UnsupportedMediaType('This resource only supports valid vcard data. Parse error: ' . $e->getMessage());
     }
     if ($vobj->name !== 'VCARD') {
         throw new DAV\Exception\UnsupportedMediaType('This collection can only support vcard objects.');
     }
     if (!isset($vobj->UID)) {
         // No UID in vcards is invalid, but we'll just add it in anyway.
         $vobj->add('UID', DAV\UUIDUtil::getUUID());
         $data = $vobj->serialize();
     }
 }
Example #8
0
 /**
  * Parses a webdav lock xml body, and returns a new Sabre\DAV\Locks\LockInfo object
  *
  * @param string $body
  * @return LockInfo
  */
 protected function parseLockRequest($body)
 {
     $result = $this->server->xml->expect('{DAV:}lockinfo', $body);
     $lockInfo = new LockInfo();
     $lockInfo->owner = $result->owner;
     $lockInfo->token = DAV\UUIDUtil::getUUID();
     $lockInfo->scope = $result->scope;
     return $lockInfo;
 }
Example #9
0
    /**
     * Updates the list of shares.
     *
     * @param mixed $calendarId
     * @param \Sabre\DAV\Xml\Element\Sharee[] $sharees
     * @return void
     */
    function updateInvites($calendarId, array $sharees)
    {
        if (!is_array($calendarId)) {
            throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
        }
        $currentInvites = $this->getInvites($calendarId);
        list($calendarId, $instanceId) = $calendarId;
        $removeStmt = $this->pdo->prepare("DELETE FROM " . $this->calendarInstancesTableName . " WHERE calendarid = ? AND share_href = ? AND access IN (2,3)");
        $updateStmt = $this->pdo->prepare("UPDATE " . $this->calendarInstancesTableName . " SET access = ?, share_displayname = ?, share_invitestatus = ? WHERE calendarid = ? AND share_href = ?");
        $insertStmt = $this->pdo->prepare('
INSERT INTO ' . $this->calendarInstancesTableName . '
    (
        calendarid,
        principaluri,
        access,
        displayname,
        uri,
        description,
        calendarorder,
        calendarcolor,
        timezone,
        transparent,
        share_href,
        share_displayname,
        share_invitestatus
    )
    SELECT
        ?,
        ?,
        ?,
        displayname,
        ?,
        description,
        calendarorder,
        calendarcolor,
        timezone,
        1,
        ?,
        ?,
        ?
    FROM ' . $this->calendarInstancesTableName . ' WHERE id = ?');
        foreach ($sharees as $sharee) {
            if ($sharee->access === \Sabre\DAV\Sharing\Plugin::ACCESS_NOACCESS) {
                // if access was set no NOACCESS, it means access for an
                // existing sharee was removed.
                $removeStmt->execute([$calendarId, $sharee->href]);
                continue;
            }
            if (is_null($sharee->principal)) {
                // If the server could not determine the principal automatically,
                // we will mark the invite status as invalid.
                $sharee->inviteStatus = \Sabre\DAV\Sharing\Plugin::INVITE_INVALID;
            } else {
                // Because sabre/dav does not yet have an invitation system,
                // every invite is automatically accepted for now.
                $sharee->inviteStatus = \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED;
            }
            foreach ($currentInvites as $oldSharee) {
                if ($oldSharee->href === $sharee->href) {
                    // This is an update
                    $sharee->properties = array_merge($oldSharee->properties, $sharee->properties);
                    $updateStmt->execute([$sharee->access, isset($sharee->properties['{DAV:}displayname']) ? $sharee->properties['{DAV:}displayname'] : null, $sharee->inviteStatus ?: $oldSharee->inviteStatus, $calendarId, $sharee->href]);
                    continue 2;
                }
            }
            // If we got here, it means it was a new sharee
            $insertStmt->execute([$calendarId, $sharee->principal, $sharee->access, \Sabre\DAV\UUIDUtil::getUUID(), $sharee->href, isset($sharee->properties['{DAV:}displayname']) ? $sharee->properties['{DAV:}displayname'] : null, $sharee->inviteStatus ?: \Sabre\DAV\Sharing\Plugin::INVITE_NORESPONSE, $instanceId]);
        }
    }
Example #10
0
    public static function CheckPrincipals($sUserName)
    {
        if (trim($sUserName) !== '') {
            $oPdo = \CApi::GetPDO();
            $dbPrefix = \CApi::GetSettingsConf('Common/DBPrefix');
            $oAccount = self::GetAccountByLogin($sUserName);
            if ($oAccount) {
                $sPrincipal = \afterlogic\DAV\Constants::PRINCIPALS_PREFIX . '/' . $sUserName;
                $oStmt = $oPdo->prepare('SELECT id FROM ' . $dbPrefix . Constants::T_PRINCIPALS . ' WHERE uri = ? LIMIT 1');
                $oStmt->execute(array($sPrincipal));
                if (count($oStmt->fetchAll()) === 0) {
                    $oStmt = $oPdo->prepare('INSERT INTO ' . $dbPrefix . Constants::T_PRINCIPALS . '
							(uri,email,displayname) VALUES (?, ?, ?)');
                    try {
                        $oStmt->execute(array($sPrincipal, $sUserName, ''));
                    } catch (Exception $e) {
                    }
                }
                $oStmt = $oPdo->prepare('SELECT principaluri FROM ' . $dbPrefix . Constants::T_CALENDARS . '
						WHERE principaluri = ?');
                $oStmt->execute(array($sPrincipal));
                if (count($oStmt->fetchAll()) === 0) {
                    $oStmt = $oPdo->prepare('INSERT INTO ' . $dbPrefix . Constants::T_CALENDARS . '
							(principaluri, displayname, uri, description, components, ctag, calendarcolor)
							VALUES (?, ?, ?, ?, ?, 1, ?)');
                    $oStmt->execute(array($sPrincipal, \CApi::ClientI18N('CALENDAR/CALENDAR_DEFAULT_NAME', $oAccount), \Sabre\DAV\UUIDUtil::getUUID(), '', 'VEVENT,VTODO', Constants::CALENDAR_DEFAULT_COLOR));
                }
                $oStmt = $oPdo->prepare('SELECT principaluri FROM ' . $dbPrefix . Constants::T_CALENDARS . '
						WHERE principaluri = ? and uri = ? LIMIT 1');
                $oStmt->execute(array($sPrincipal, Constants::CALENDAR_DEFAULT_NAME));
                if (count($oStmt->fetchAll()) !== 0) {
                    $oStmt = $oPdo->prepare('UPDATE ' . $dbPrefix . Constants::T_CALENDARS . '
							SET uri = ? WHERE principaluri = ? and uri = ?');
                    $oStmt->execute(array(\Sabre\DAV\UUIDUtil::getUUID(), $sPrincipal, Constants::CALENDAR_DEFAULT_NAME));
                }
                $oStmt = $oPdo->prepare('SELECT principaluri FROM ' . $dbPrefix . Constants::T_ADDRESSBOOKS . '
						WHERE principaluri = ? and uri = ? LIMIT 1');
                $oStmt->execute(array($sPrincipal, Constants::ADDRESSBOOK_DEFAULT_NAME));
                $bHasDefaultAddressbooks = count($oStmt->fetchAll()) != 0;
                $oStmt->execute(array($sPrincipal, Constants::ADDRESSBOOK_DEFAULT_NAME_OLD));
                $bHasOldDefaultAddressbooks = count($oStmt->fetchAll()) != 0;
                $oStmt->execute(array($sPrincipal, Constants::ADDRESSBOOK_COLLECTED_NAME));
                $bHasCollectedAddressbooks = count($oStmt->fetchAll()) != 0;
                $stmt1 = $oPdo->prepare('INSERT INTO ' . $dbPrefix . Constants::T_ADDRESSBOOKS . '
						(principaluri, displayname, uri, description, ctag)
						VALUES (?, ?, ?, ?, 1)');
                if (!$bHasDefaultAddressbooks) {
                    if ($bHasOldDefaultAddressbooks) {
                        $oStmt = $oPdo->prepare('UPDATE ' . $dbPrefix . Constants::T_ADDRESSBOOKS . '
								SET uri = ? WHERE principaluri = ? and uri = ?');
                        $oStmt->execute(array(Constants::ADDRESSBOOK_DEFAULT_NAME, $sPrincipal, Constants::ADDRESSBOOK_DEFAULT_NAME_OLD));
                    } else {
                        $stmt1->execute(array($sPrincipal, Constants::ADDRESSBOOK_DEFAULT_DISPLAY_NAME, Constants::ADDRESSBOOK_DEFAULT_NAME, Constants::ADDRESSBOOK_DEFAULT_DISPLAY_NAME));
                    }
                }
                if (!$bHasCollectedAddressbooks) {
                    $stmt1->execute(array($sPrincipal, Constants::ADDRESSBOOK_COLLECTED_DISPLAY_NAME, Constants::ADDRESSBOOK_COLLECTED_NAME, Constants::ADDRESSBOOK_COLLECTED_DISPLAY_NAME));
                }
            }
        }
    }
Example #11
0
 /**
  * @param int $iUserId
  * @param string $sEmail
  * @return bool
  */
 public function UpdateSuggestTable($iUserId, $aEmails)
 {
     $bResult = false;
     $this->Init($iUserId);
     $oDefautltAB = $this->getAddressBook($iUserId, \afterlogic\DAV\Constants::ADDRESSBOOK_DEFAULT_NAME);
     $oCollectedAB = $this->getAddressBook($iUserId, \afterlogic\DAV\Constants::ADDRESSBOOK_COLLECTED_NAME);
     $aCollectedContactItems = $this->getObjectItems($iUserId, $oCollectedAB);
     foreach ($aEmails as $sEmail => $sName) {
         $mFindContact = false;
         if ($aCollectedContactItems) {
             foreach ($aCollectedContactItems as $oCollectedContactItem) {
                 $oVCard = \Sabre\VObject\Reader::read($oCollectedContactItem->get());
                 if (isset($oVCard->EMAIL)) {
                     foreach ($oVCard->EMAIL as $oEmail) {
                         if (strtolower((string) $oEmail) == strtolower($sEmail)) {
                             $mFindContact = $oCollectedContactItem;
                             break;
                         }
                     }
                 }
                 unset($oVCard);
             }
         }
         $aDefaultContactIds = $this->searchContactItemsByEmail($iUserId, $sEmail, $oDefautltAB);
         if (count($aDefaultContactIds) === 0) {
             if ($mFindContact === false) {
                 $sUUID = \Sabre\DAV\UUIDUtil::getUUID();
                 $oContact = new CContact();
                 $oContact->FullName = $sName;
                 $oContact->HomeEmail = $sEmail;
                 $oContact->IdContactStr = $sUUID;
                 $oVCard = new \Sabre\VObject\Component\VCard();
                 $oVCard->{'X-AFTERLOGIC-USE-FREQUENCY'} = '1';
                 CApiContactsVCardHelper::UpdateVCardFromContact($oContact, $oVCard);
                 $oCollectedAB->createFile($sUUID . '.vcf', $oVCard->serialize());
                 $bResult = true;
             } else {
                 if ($mFindContact instanceof \Sabre\CardDAV\Card) {
                     $oVCard = \Sabre\VObject\Reader::read($mFindContact->get());
                     if (isset($oVCard->{'X-AFTERLOGIC-USE-FREQUENCY'})) {
                         $oVCard->{'X-AFTERLOGIC-USE-FREQUENCY'} = (int) $oVCard->{'X-AFTERLOGIC-USE-FREQUENCY'}->getValue() + 1;
                     } else {
                         $oVCard->{'X-AFTERLOGIC-USE-FREQUENCY'} = '1';
                     }
                     $mFindContact->put($oVCard->serialize());
                     unset($oVCard);
                 }
             }
         } else {
             foreach ($aDefaultContactIds as $sDefaultContactId) {
                 $mDefaultContact = $this->geItem($iUserId, $oDefautltAB, $sDefaultContactId);
                 if ($mDefaultContact !== false) {
                     $oVCard = \Sabre\VObject\Reader::read($mDefaultContact->get());
                     if (isset($oVCard->{'X-AFTERLOGIC-USE-FREQUENCY'})) {
                         $oVCard->{'X-AFTERLOGIC-USE-FREQUENCY'} = (int) $oVCard->{'X-AFTERLOGIC-USE-FREQUENCY'}->getValue() + 1;
                     } else {
                         $oVCard->{'X-AFTERLOGIC-USE-FREQUENCY'} = '1';
                     }
                     $mDefaultContact->put($oVCard->serialize());
                     unset($oVCard);
                 }
             }
             if ($mFindContact instanceof \Sabre\CardDAV\Card) {
                 $mFindContact->delete();
             }
         }
     }
     return $bResult;
 }
Example #12
0
 /**
  * Parses a webdav lock xml body, and returns a new Sabre\DAV\Locks\LockInfo object
  *
  * @param string $body
  * @return DAV\Locks\LockInfo
  */
 protected function parseLockRequest($body)
 {
     // Fixes an XXE vulnerability on PHP versions older than 5.3.23 or
     // 5.4.13.
     $previous = libxml_disable_entity_loader(true);
     $xml = simplexml_load_string(DAV\XMLUtil::convertDAVNamespace($body), null, LIBXML_NOWARNING);
     libxml_disable_entity_loader($previous);
     $xml->registerXPathNamespace('d', 'urn:DAV');
     $lockInfo = new LockInfo();
     $children = $xml->children("urn:DAV");
     $lockInfo->owner = (string) $children->owner;
     $lockInfo->token = DAV\UUIDUtil::getUUID();
     $lockInfo->scope = count($xml->xpath('d:lockscope/d:exclusive')) > 0 ? LockInfo::EXCLUSIVE : LockInfo::SHARED;
     return $lockInfo;
 }
Example #13
0
 public function PopulateByVCard($sVCard, $sEtag = '')
 {
     $this->Properties = array();
     if (!empty($sEtag)) {
         $this->Etag = $sEtag;
     }
     try {
         $oVCard = \Sabre\VObject\Reader::read($sVCard);
     } catch (\Exception $oExc) {
     }
     $aProperties = array();
     if ($oVCard) {
         $bOldVersion = empty($oVCard->VERSION) ? false : \in_array((string) $oVCard->VERSION, array('2.1', '2.0', '1.0'));
         $this->IdContactStr = $oVCard->UID ? (string) $oVCard->UID : \Sabre\DAV\UUIDUtil::getUUID();
         if (isset($oVCard->FN) && '' !== \trim($oVCard->FN)) {
             $sValue = $this->getPropertyValueHelper($oVCard->FN, $bOldVersion);
             $aProperties[] = new Property(PropertyType::FULLNAME, $sValue);
         }
         if (isset($oVCard->NICKNAME) && '' !== \trim($oVCard->NICKNAME)) {
             $sValue = $sValue = $this->getPropertyValueHelper($oVCard->NICKNAME, $bOldVersion);
             $aProperties[] = new Property(PropertyType::NICK_NAME, $sValue);
         }
         if (isset($oVCard->NOTE) && '' !== \trim($oVCard->NOTE)) {
             $sValue = $this->getPropertyValueHelper($oVCard->NOTE, $bOldVersion);
             $aProperties[] = new Property(PropertyType::NOTE, $sValue);
         }
         if (isset($oVCard->N)) {
             $aNames = $oVCard->N->getParts();
             foreach ($aNames as $iIndex => $sValue) {
                 $sValue = \trim($sValue);
                 if ($bOldVersion && !isset($oVCard->N->parameters['CHARSET'])) {
                     if (0 < \strlen($sValue)) {
                         $sEncValue = @\utf8_encode($sValue);
                         if (0 === \strlen($sEncValue)) {
                             $sEncValue = $sValue;
                         }
                         $sValue = $sEncValue;
                     }
                 }
                 $sValue = \MailSo\Base\Utils::Utf8Clear($sValue);
                 switch ($iIndex) {
                     case 0:
                         $aProperties[] = new Property(PropertyType::LAST_NAME, $sValue);
                         break;
                     case 1:
                         $aProperties[] = new Property(PropertyType::FIRST_NAME, $sValue);
                         break;
                     case 2:
                         $aProperties[] = new Property(PropertyType::MIDDLE_NAME, $sValue);
                         break;
                     case 3:
                         $aProperties[] = new Property(PropertyType::NAME_PREFIX, $sValue);
                         break;
                     case 4:
                         $aProperties[] = new Property(PropertyType::NAME_SUFFIX, $sValue);
                         break;
                 }
             }
         }
         if (isset($oVCard->EMAIL)) {
             $this->addArrayPropertyHelper($aProperties, $oVCard->EMAIL, PropertyType::EMAIl);
         }
         if (isset($oVCard->URL)) {
             $this->addArrayPropertyHelper($aProperties, $oVCard->URL, PropertyType::WEB_PAGE);
         }
         if (isset($oVCard->TEL)) {
             $this->addArrayPropertyHelper($aProperties, $oVCard->TEL, PropertyType::PHONE);
         }
         $this->Properties = $aProperties;
         if (isset($oVCard->CATEGORIES)) {
             $this->Tags = (array) $oVCard->CATEGORIES->getParts();
             $this->Tags = \is_array($this->Tags) ? $this->Tags : array();
             $this->Tags = \array_map('trim', $this->Tags);
         }
     }
     $this->UpdateDependentValues();
 }
Example #14
0
 /**
  * Creates a new calendar for a principal.
  *
  * If the creation was a success, an id must be returned that can be used to reference
  * this calendar in other methods, such as updateCalendar.
  *
  * This function must return a server-wide unique id that can be used
  * later to reference the calendar.
  *
  * @param string $principalUri
  * @param string $calendarUri
  * @param array $properties
  * @return string|int
  */
 function createCalendar($principalUri, $calendarUri, array $properties)
 {
     $id = DAV\UUIDUtil::getUUID();
     $this->calendars[] = array_merge(['id' => $id, 'principaluri' => $principalUri, 'uri' => $calendarUri, '{' . CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet(['VEVENT', 'VTODO'])], $properties);
     return $id;
 }
Example #15
0
 /**
  * @param string $sEmail
  * @param string $sVcfData
  *
  * @return int
  */
 public function ImportVcfFile($sEmail, $sVcfData)
 {
     $iCount = 0;
     if ($this->IsActive() && \is_string($sVcfData)) {
         $sVcfData = \trim($sVcfData);
         if ("" === \substr($sVcfData, 0, 3)) {
             $sVcfData = \substr($sVcfData, 3);
         }
         $oVCardSplitter = null;
         try {
             $oVCardSplitter = new \Sabre\VObject\Splitter\VCard($sVcfData);
         } catch (\Exception $oExc) {
             $this->Logger()->WriteException($oExc);
         }
         if ($oVCardSplitter) {
             $oContact = new \RainLoop\Providers\AddressBook\Classes\Contact();
             $oVCard = null;
             while ($oVCard = $oVCardSplitter->getNext()) {
                 if ($oVCard instanceof \Sabre\VObject\Component\VCard) {
                     \MailSo\Base\Utils::ResetTimeLimit();
                     if (empty($oVCard->UID)) {
                         $oVCard->UID = \Sabre\DAV\UUIDUtil::getUUID();
                     }
                     $oContact->PopulateByVCard($oVCard->serialize());
                     if (0 < \count($oContact->Properties)) {
                         if ($this->ContactSave($sEmail, $oContact)) {
                             $iCount++;
                         }
                     }
                     $oContact->Clear();
                 }
             }
         }
     }
     return $iCount;
 }
Example #16
0
 /**
  * Checks if the submitted iCalendar data is in fact, valid.
  *
  * An exception is thrown if it's not.
  *
  * @param resource|string $data
  * @param bool $modified Should be set to true, if this event handler
  *                       changed &$data.
  * @return void
  */
 protected function validateVCard(&$data, &$modified)
 {
     // If it's a stream, we convert it to a string first.
     if (is_resource($data)) {
         $data = stream_get_contents($data);
     }
     $before = md5($data);
     // Converting the data to unicode, if needed.
     $data = DAV\StringUtil::ensureUTF8($data);
     if (md5($data) !== $before) {
         $modified = true;
     }
     try {
         // If the data starts with a [, we can reasonably assume we're dealing
         // with a jCal object.
         if (substr($data, 0, 1) === '[') {
             $vobj = VObject\Reader::readJson($data);
             // Converting $data back to iCalendar, as that's what we
             // technically support everywhere.
             $data = $vobj->serialize();
             $modified = true;
         } else {
             $vobj = VObject\Reader::read($data);
         }
     } catch (VObject\ParseException $e) {
         throw new DAV\Exception\UnsupportedMediaType('This resource only supports valid vCard or jCard data. Parse error: ' . $e->getMessage());
     }
     if ($vobj->name !== 'VCARD') {
         throw new DAV\Exception\UnsupportedMediaType('This collection can only support vcard objects.');
     }
     if (!isset($vobj->UID)) {
         // No UID in vcards is invalid, but we'll just add it in anyway.
         $vobj->add('UID', DAV\UUIDUtil::getUUID());
         $data = $vobj->serialize();
         $modified = true;
     }
 }
Example #17
0
 /**
  * Parses a webdav lock xml body, and returns a new Sabre\DAV\Locks\LockInfo object
  *
  * @param string $body
  * @return DAV\Locks\LockInfo
  */
 protected function parseLockRequest($body)
 {
     $xml = simplexml_load_string(DAV\XMLUtil::convertDAVNamespace($body), null, LIBXML_NOWARNING);
     $xml->registerXPathNamespace('d', 'urn:DAV');
     $lockInfo = new LockInfo();
     $children = $xml->children("urn:DAV");
     $lockInfo->owner = (string) $children->owner;
     $lockInfo->token = DAV\UUIDUtil::getUUID();
     $lockInfo->scope = count($xml->xpath('d:lockscope/d:exclusive')) > 0 ? LockInfo::EXCLUSIVE : LockInfo::SHARED;
     return $lockInfo;
 }
Example #18
0
 /**
  * Event handler for the 'schedule' event.
  *
  * This handler attempts to look at local accounts to deliver the
  * scheduling object.
  *
  * @param ITip\Message $iTipMessage
  * @return void
  */
 function scheduleLocalDelivery(ITip\Message $iTipMessage)
 {
     $aclPlugin = $this->server->getPlugin('acl');
     // Local delivery is not available if the ACL plugin is not loaded.
     if (!$aclPlugin) {
         return;
     }
     $caldavNS = '{' . Plugin::NS_CALDAV . '}';
     $principalUri = $aclPlugin->getPrincipalByUri($iTipMessage->recipient);
     if (!$principalUri) {
         $iTipMessage->scheduleStatus = '3.7;Could not find principal.';
         return;
     }
     // We found a principal URL, now we need to find its inbox.
     // Unfortunately we may not have sufficient privileges to find this, so
     // we are temporarily turning off ACL to let this come through.
     //
     // Once we support PHP 5.5, this should be wrapped in a try..finally
     // block so we can ensure that this privilege gets added again after.
     $this->server->removeListener('propFind', [$aclPlugin, 'propFind']);
     $result = $this->server->getProperties($principalUri, ['{DAV:}principal-URL', $caldavNS . 'calendar-home-set', $caldavNS . 'schedule-inbox-URL', $caldavNS . 'schedule-default-calendar-URL', '{http://sabredav.org/ns}email-address']);
     // Re-registering the ACL event
     $this->server->on('propFind', [$aclPlugin, 'propFind'], 20);
     if (!isset($result[$caldavNS . 'schedule-inbox-URL'])) {
         $iTipMessage->scheduleStatus = '5.2;Could not find local inbox';
         return;
     }
     if (!isset($result[$caldavNS . 'calendar-home-set'])) {
         $iTipMessage->scheduleStatus = '5.2;Could not locate a calendar-home-set';
         return;
     }
     if (!isset($result[$caldavNS . 'schedule-default-calendar-URL'])) {
         $iTipMessage->scheduleStatus = '5.2;Could not find a schedule-default-calendar-URL property';
         return;
     }
     $calendarPath = $result[$caldavNS . 'schedule-default-calendar-URL']->getHref();
     $homePath = $result[$caldavNS . 'calendar-home-set']->getHref();
     $inboxPath = $result[$caldavNS . 'schedule-inbox-URL']->getHref();
     if ($iTipMessage->method === 'REPLY') {
         $privilege = 'schedule-deliver-reply';
     } else {
         $privilege = 'schedule-deliver-invite';
     }
     if (!$aclPlugin->checkPrivileges($inboxPath, $caldavNS . $privilege, DAVACL\Plugin::R_PARENT, false)) {
         $iTipMessage->scheduleStatus = '3.8;organizer did not have the ' . $privilege . ' privilege on the attendees inbox';
         return;
     }
     // Next, we're going to find out if the item already exits in one of
     // the users' calendars.
     $uid = $iTipMessage->uid;
     $newFileName = 'sabredav-' . \Sabre\DAV\UUIDUtil::getUUID() . '.ics';
     $home = $this->server->tree->getNodeForPath($homePath);
     $inbox = $this->server->tree->getNodeForPath($inboxPath);
     $currentObject = null;
     $objectNode = null;
     $isNewNode = false;
     $result = $home->getCalendarObjectByUID($uid);
     if ($result) {
         // There was an existing object, we need to update probably.
         $objectPath = $homePath . '/' . $result;
         $objectNode = $this->server->tree->getNodeForPath($objectPath);
         $oldICalendarData = $objectNode->get();
         $currentObject = Reader::read($oldICalendarData);
     } else {
         $isNewNode = true;
     }
     $broker = new ITip\Broker();
     $newObject = $broker->processMessage($iTipMessage, $currentObject);
     $inbox->createFile($newFileName, $iTipMessage->message->serialize());
     if (!$newObject) {
         // We received an iTip message referring to a UID that we don't
         // have in any calendars yet, and processMessage did not give us a
         // calendarobject back.
         //
         // The implication is that processMessage did not understand the
         // iTip message.
         $iTipMessage->scheduleStatus = '5.0;iTip message was not processed by the server, likely because we didn\'t understand it.';
         return;
     }
     // Note that we are bypassing ACL on purpose by calling this directly.
     // We may need to look a bit deeper into this later. Supporting ACL
     // here would be nice.
     if ($isNewNode) {
         $calendar = $this->server->tree->getNodeForPath($calendarPath);
         $calendar->createFile($newFileName, $newObject->serialize());
     } else {
         // If the message was a reply, we may have to inform other
         // attendees of this attendees status. Therefore we're shooting off
         // another itipMessage.
         if ($iTipMessage->method === 'REPLY') {
             $this->processICalendarChange($oldICalendarData, $newObject, [$iTipMessage->recipient], [$iTipMessage->sender]);
         }
         $objectNode->put($newObject->serialize());
     }
     $iTipMessage->scheduleStatus = '1.2;Message delivered locally';
 }