Beispiel #1
0
/**
 * Standard tool for making payments.
 * @class Assets payment
 * @constructor
 * @param {array} $options Override various options for this tool
 *  @param {string} $options.payments can be "authnet" or "stripe"
 *  @param {string} $options.amount the amount to pay.
 *  @param {double} [$options.currency="usd"] the currency to pay in. (authnet supports only "usd")
 *  @param {string} [$options.payButton] Can override the title of the pay button
 *  @param {String} [$options.publisherId=Users::communityId()] The publisherId of the Assets/product or Assets/service stream
 *  @param {String} [$options.streamName] The name of the Assets/product or Assets/service stream
 *  @param {string} [$options.name=Users::communityName()] The name of the organization the user will be paying
 *  @param {string} [$options.image] The url pointing to a square image of your brand or product. The recommended minimum size is 128x128px.
 *  @param {string} [$options.description=null] A short name or description of the product or service being purchased.
 *  @param {string} [$options.panelLabel] The label of the payment button in the Stripe Checkout form (e.g. "Pay {{amount}}", etc.). If you include {{amount}}, it will be replaced by the provided amount. Otherwise, the amount will be appended to the end of your label.
 *  @param {string} [$options.zipCode] Specify whether Stripe Checkout should validate the billing ZIP code (true or false). The default is false.
 *  @param {boolean} [$options.billingAddress] Specify whether Stripe Checkout should collect the user's billing address (true or false). The default is false.
 *  @param {boolean} [$options.shippingAddress] Specify whether Checkout should collect the user's shipping address (true or false). The default is false.
 *  @param {string} [$options.email=Users::loggedInUser(true)->emailAddress] You can use this to override the email address, if any, provided to Stripe Checkout to be pre-filled.
 *  @param {boolean} [$options.allowRememberMe=true] Specify whether to include the option to "Remember Me" for future purchases (true or false).
 *  @param {boolean} [$options.bitcoin=false] Specify whether to accept Bitcoin (true or false). 
 *  @param {boolean} [$options.alipay=false] Specify whether to accept Alipay ('auto', true, or false). 
 *  @param {boolean} [$options.alipayReusable=false] Specify if you need reusable access to the customer's Alipay account (true or false).
 */
function Assets_payment_tool($options)
{
    Q_Valid::requireFields(array('payments', 'amount'), $options, true);
    if (empty($options['name'])) {
        $options['name'] = Users::communityName();
    }
    if (!empty($options['image'])) {
        $options['image'] = Q_Html::themedUrl($options['image']);
    }
    $options['payments'] = strtolower($options['payments']);
    if (empty($options['email'])) {
        $options['email'] = Users::loggedInUser(true)->emailAddress;
    }
    $payments = ucfirst($options['payments']);
    $currency = strtolower(Q::ifset($options, 'currency', 'usd'));
    if ($payments === 'Authnet' and $currency !== 'usd') {
        throw new Q_Exception("Authnet doesn't support currencies other than USD", 'currency');
    }
    $className = "Assets_Payments_{$payments}";
    switch ($payments) {
        case 'Authnet':
            $adapter = new $className($options);
            $token = $options['token'] = $adapter->authToken();
            $testing = $options['testing'] = Q_Config::expect('Assets', 'payments', $lcpayments, 'testing');
            $action = $options['action'] = $testing ? "https://test.authorize.net/profile/manage" : "https://secure.authorize.net/profile/manage";
            break;
        case 'Stripe':
            $publishableKey = Q_Config::expect('Assets', 'payments', 'stripe', 'publishableKey');
            break;
    }
    $titles = array('Authnet' => 'Authorize.net', 'Stripe' => 'Stripe');
    Q_Response::setToolOptions($options);
    $payButton = Q::ifset($options, 'payButton', "Pay with " . $titles[$payments]);
    return Q::view("Assets/tool/payment/{$payments}.php", compact('token', 'publishableKey', 'action', 'payButton'));
}
function Streams_0_8_4_Streams_mysql()
{
    $app = Q_Config::expect('Q', 'app');
    $communityId = Users::communityId();
    $user = Users_User::fetch($communityId);
    // avatar for the App user
    $avatar = new Streams_Avatar();
    $avatar->toUserId = $communityId;
    $avatar->publisherId = $communityId;
    $avatar->username = $user->username;
    $avatar->firstName = Users::communityName();
    $avatar->lastName = Users::communitySuffix();
    $avatar->icon = $user->icon;
    $avatar->save();
    $avatar2 = new Streams_Avatar();
    $avatar2->copyFrom($avatar, null, false, true);
    $avatar->toUserId = '';
    $avatar->save();
    // access stream for managing app roles
    $stream = new Streams_Stream();
    $stream->publisherId = Users::communityId();
    $stream->name = 'Streams/contacts';
    $stream->type = 'Streams/resource';
    $stream->title = "Contacts";
    $stream->setAttribute('prefixes', array("Users/", "{$app}/"));
    $stream->save();
    // access stream for managing app roles
    $stream = new Streams_Stream();
    $stream->publisherId = $app;
    $stream->name = 'Streams/labels';
    $stream->type = 'Streams/resource';
    $stream->title = "Labels";
    $stream->setAttribute('prefixes', array("Users/", "{$app}/"));
    $stream->save();
    // access for managing app contacts
    $access = new Streams_Access();
    $access->publisherId = $communityId;
    $access->streamName = 'Streams/contacts';
    $access->ofUserId = '';
    $access->ofContactLabel = "{$app}/admins";
    $access->readLevel = Streams::$READ_LEVEL['messages'];
    $access->writeLevel = Streams::$WRITE_LEVEL['edit'];
    $access->adminLevel = Streams::$ADMIN_LEVEL['manage'];
    $access->save();
    // access for managing app roles
    $access = new Streams_Access();
    $access->publisherId = $communityId;
    $access->streamName = 'Streams/labels';
    $access->ofUserId = '';
    $access->ofContactLabel = "{$app}/admins";
    $access->readLevel = Streams::$READ_LEVEL['messages'];
    $access->writeLevel = Streams::$WRITE_LEVEL['edit'];
    $access->adminLevel = Streams::$ADMIN_LEVEL['manage'];
    $access->save();
}
function Users_before_Q_responseExtras()
{
    Q_Response::addScript('plugins/Users/js/Users.js');
    $app = Q_Config::expect('Q', 'app');
    $requireLogin = Q_Config::get('Users', 'requireLogin', array());
    $rl_array = array();
    foreach ($requireLogin as $rl => $value) {
        $rl_array[Q_Uri::url($rl)] = $value;
    }
    if (!Q_Request::isAjax()) {
        Q_Response::setScriptData('Q.plugins.Users.requireLogin', $rl_array);
        $successUrl = Q_Config::get('Users', 'uris', "{$app}/successUrl", "{$app}/home");
        $afterActivate = Q_Config::get('Users', 'uris', "{$app}/afterActivate", $successUrl);
        $loginOptions = Q_Config::get('Users', 'login', array("identifierType" => 'email,mobile', "userQueryUri" => 'Users/user', "using" => "native,facebook", "noRegister" => false));
        $loginOptions["afterActivate"] = Q_Uri::url($afterActivate);
        $loginOptions["successUrl"] = Q_Uri::url($successUrl);
        Q_Response::setScriptData('Q.plugins.Users.login.serverOptions', $loginOptions);
        $setIdentifierOptions = Q::take($loginOptions, array('identifierType'));
        Q_Response::setScriptData('Q.plugins.Users.setIdentifier.serverOptions', $setIdentifierOptions);
    }
    $fb_app_info = Q_Config::get('Users', 'facebookApps', $app, array());
    if ($fb_app_info) {
        unset($fb_app_info['secret']);
        Q_Response::setScriptData("Q.plugins.Users.facebookApps.{$app}", $fb_app_info);
    }
    if ($node_server_url = Q_Config::get('Users', 'nodeServer', 'url', null)) {
        Q_Response::setScriptData("Q.plugins.Users.nodeServer", parse_url($node_server_url));
    }
    if (Q_Config::get('Users', 'showLoggedInUser', true)) {
        $user = Q_Session::id() ? Users::loggedInUser() : null;
        if ($user) {
            $u = $user->exportArray();
            $u['sessionCount'] = $user->sessionCount;
            Q_Response::setScriptData("Q.plugins.Users.loggedInUser", $u);
            Q_Response::addScriptLine("Q.plugins.Users.loggedInUser = new Q.plugins.Users.User(Q.plugins.Users.loggedInUser);");
        }
    }
    Q_Response::setScriptData('Q.plugins.Users.communityId', Users::communityId());
    Q_Response::setScriptData('Q.plugins.Users.communityName', Users::communityName());
    Q_Response::setScriptData('Q.plugins.Users.communitySuffix', Users::communitySuffix());
    Q_Response::setScriptData('Q.plugins.Users.hinted', Q::ifset($_SESSION, 'Users', 'hinted', array()));
    if ($sizes = Q_Config::expect('Users', 'icon', 'sizes')) {
        sort($sizes);
        Q_Response::setScriptData('Q.plugins.Users.icon.sizes', $sizes);
    }
    $defaultSize = Q_Config::get('Users', 'icon', 'defaultSize', 40);
    Q_Response::setScriptData('Q.plugins.Users.icon.defaultSize', $defaultSize);
    Q_Response::addStylesheet("plugins/Users/css/Users.css");
}
function Streams_0_8_1_Streams_mysql()
{
    $app = Q_Config::expect('Q', 'app');
    $commmunityId = Users::communityId();
    // template for community stream
    $stream = new Streams_Stream();
    $stream->publisherId = '';
    $stream->name = 'Streams/community/';
    $stream->type = 'Streams/template';
    $stream->title = "Community";
    $stream->content = '';
    $stream->readLevel = Streams::$READ_LEVEL['content'];
    $stream->writeLevel = Streams::$WRITE_LEVEL['join'];
    $stream->adminLevel = Streams::$ADMIN_LEVEL['invite'];
    $stream->save();
    // app community stream, for announcements
    Streams::create($commmunityId, $commmunityId, 'Streams/community', array('skipAccess' => true, 'name' => 'Streams/community/main', 'title' => Users::communityName()));
    // symlink the labels folder
    if (!file_exists('Streams')) {
        Q_Utils::symlink(STREAMS_PLUGIN_FILES_DIR . DS . 'Streams' . DS . 'icons' . DS . 'labels' . DS . 'Streams', USERS_PLUGIN_FILES_DIR . DS . 'Users' . DS . 'icons' . DS . 'labels' . DS . 'Streams');
    }
}
Beispiel #5
0
<div id='dashboard'>
	<h1><?php 
echo Users::communityName();
?>
</h1>

	<div id="dashboard_user">
		<?php 
if ($user) {
    ?>
			<?php 
    echo Q::tool("Users/avatar", array('userId' => $user->id, 'icon' => 50, 'short' => true), 'dashboard');
    ?>
		<?php 
} else {
    ?>
			<a href="#login" class="MyApp_login">log in</a>
		<?php 
}
?>
		<div id="dashboard_user_contextual" class="Q_contextual" data-handler="MyApp.userContextual">
			<ul class="Q_listing">
				<?php 
if ($user) {
    ?>
					<?php 
    if (!$user->mobileNumber) {
        ?>
						<li data-action="setIdentifier">set mobile number</li>
					<?php 
    } elseif (!$user->emailAddress) {
function Streams_after_Users_User_saveExecute($params)
{
    // If the username or icon was somehow modified,
    // update all the avatars for this publisher
    $modifiedFields = $params['modifiedFields'];
    $user = $params['row'];
    $updates = array();
    if (isset($modifiedFields['username'])) {
        $updates['username'] = $modifiedFields['username'];
    }
    if (isset($modifiedFields['icon'])) {
        $updates['icon'] = $modifiedFields['icon'];
    }
    if ($user->id === Users::communityId()) {
        $firstName = Users::communityName();
        $lastName = Users::communitySuffix();
        $firstName = $firstName ? $firstName : "";
        $lastName = $lastName ? $lastName : "";
    } else {
        $firstName = Q::ifset(Streams::$cache, 'register', 'first', '');
        $lastName = Q::ifset(Streams::$cache, 'register', 'last', '');
    }
    if ($params['inserted']) {
        // create some standard streams for them
        $onInsert = Q_Config::get('Streams', 'onInsert', 'Users_User', array());
        if (!$onInsert) {
            return;
        }
        $p = new Q_Tree();
        $p->load(STREAMS_PLUGIN_CONFIG_DIR . DS . 'streams.json');
        $p->load(APP_CONFIG_DIR . DS . 'streams.json');
        $values = array('Streams/user/firstName' => $firstName, 'Streams/user/lastName' => $lastName);
        // Check for user data from facebook
        if (!empty(Users::$cache['facebookUserData'])) {
            $userData = Users::$cache['facebookUserData'];
            foreach ($userData as $name_fb => $value) {
                foreach ($p->getAll() as $name => $info) {
                    if (isset($info['name_fb']) and $info['name_fb'] === $name_fb) {
                        $onInsert[] = $name;
                        $values[$name] = $value;
                    }
                }
            }
        }
        foreach ($onInsert as $name) {
            $stream = Streams::fetchOne($user->id, $user->id, $name);
            if (!$stream) {
                // it shouldn't really be in the db yet
                $stream = new Streams_Stream();
                $stream->publisherId = $user->id;
                $stream->name = $name;
            }
            $stream->type = $p->expect($name, "type");
            $stream->title = $p->expect($name, "title");
            $stream->content = $p->get($name, "content", '');
            // usually empty
            $stream->readLevel = $p->get($name, 'readLevel', Streams_Stream::$DEFAULTS['readLevel']);
            $stream->writeLevel = $p->get($name, 'writeLevel', Streams_Stream::$DEFAULTS['writeLevel']);
            $stream->adminLevel = $p->get($name, 'adminLevel', Streams_Stream::$DEFAULTS['adminLevel']);
            if ($name === "Streams/user/icon") {
                $sizes = Q_Config::expect('Users', 'icon', 'sizes');
                sort($sizes);
                $stream->setAttribute('sizes', $sizes);
                $stream->icon = $user->iconUrl();
            }
            if (isset($values[$name])) {
                $stream->content = $values[$name];
            }
            $stream->save();
            // this also inserts avatars
            $o = array('userId' => $user->id, 'skipAccess' => true);
            $so = $p->get($name, "subscribe", array());
            if ($so === false) {
                $stream->join($o);
            } else {
                $stream->subscribe(array_merge($o, $so));
            }
        }
        // Save a greeting stream, to be edited
        $communityId = Users::communityId();
        Streams::create($user->id, $user->id, "Streams/greeting", array('name' => "Streams/greeting/{$communityId}"));
        // Create some standard labels
        $label = new Users_Label();
        $label->userId = $user->id;
        $label->label = 'Streams/invited';
        $label->icon = 'labels/Streams/invited';
        $label->title = 'People I invited';
        $label->save(true);
        $label2 = new Users_Label();
        $label2->userId = $user->id;
        $label2->label = 'Streams/invitedMe';
        $label2->icon = 'labels/Streams/invitedMe';
        $label2->title = 'Who invited me';
        $label2->save(true);
        // By default, users they invite should see their full name
        $access = new Streams_Access();
        $access->publisherId = $user->id;
        $access->streamName = 'Streams/user/firstName';
        $access->ofUserId = '';
        $access->ofContactLabel = 'Streams/invited';
        $access->grantedByUserId = $user->id;
        $access->readLevel = Streams::$READ_LEVEL['content'];
        $access->writeLevel = -1;
        $access->adminLevel = -1;
        $access->save();
        $access = new Streams_Access();
        $access->publisherId = $user->id;
        $access->streamName = 'Streams/user/lastName';
        $access->ofUserId = '';
        $access->ofContactLabel = 'Streams/invited';
        $access->grantedByUserId = $user->id;
        $access->readLevel = Streams::$READ_LEVEL['content'];
        $access->writeLevel = -1;
        $access->adminLevel = -1;
        $access->save();
        // NOTE: the above saving of access caused Streams::updateAvatar to run,
        // insert a Streams_Avatar row for the new user, and properly configure it.
    } else {
        if ($modifiedFields) {
            if ($updates) {
                Streams_Avatar::update()->set($updates)->where(array('publisherId' => $user->id))->execute();
            }
            foreach ($modifiedFields as $field => $value) {
                $name = Q_Config::get('Streams', 'onUpdate', 'Users_User', $field, null);
                if (!$name) {
                    continue;
                }
                $stream = isset(Streams::$beingSaved[$field]) ? Streams::$beingSaved[$field] : Streams::fetchOne($user->id, $user->id, $name);
                if (!$stream) {
                    // it should probably already be in the db
                    continue;
                }
                $stream->content = $value;
                if ($name === "Streams/user/icon") {
                    $sizes = Q_Config::expect('Users', 'icon', 'sizes');
                    sort($sizes);
                    $attributes = $stream->attributes;
                    $stream->setAttribute('sizes', $sizes);
                    $stream->icon = $changes['icon'] = $user->iconUrl();
                }
                Streams::$beingSavedQuery = $stream->changed($user->id);
            }
        }
    }
}
Beispiel #7
0
if (Q_Request::platform() == 'android') {
    ?>
, target-densitydpi=medium-dpi<?php 
}
?>
" />
	<meta name="mobile-web-app-capable" content="yes" />
	<link rel="manifest" href="<?php 
echo Q_Html::themedUrl('manifest.json');
?>
">
	<meta name="theme-color" content="#f8f8f8">
	<meta name="apple-mobile-web-app-status-bar-style" content="translucent" />
	<meta name="apple-mobile-web-app-capable" content="yes" />
	<meta name="apple-mobile-web-app-title" content="<?php 
echo Q_Html::text(Users::communityName());
?>
">
	<meta name="mobile-web-app-capable" content="yes">
	<?php 
if (Q_Request::platform() !== 'android') {
    ?>
 
	<link rel="apple-touch-icon-precomposed" sizes="76x76" href="<?php 
    echo Q_Html::themedUrl('img/icon/76.png');
    ?>
" />
	<link rel="apple-touch-icon-precomposed" sizes="120x120" href="<?php 
    echo Q_Html::themedUrl('img/icon/120.png');
    ?>
" />
Beispiel #8
0
 function resendActivationMessage($view = null, $fields = array(), $options = array())
 {
     if (!isset($view)) {
         $view = Q_Config::get('Users', 'transactional', 'resend', 'sms', Q_Config::get('Users', 'transactional', 'resend', 'sms', 'Users/sms/activation.php'));
     }
     $user = $this->get('user', null);
     if (!$user) {
         $user = new Users_User();
         $user->id = $this->userId;
         if (!$user->retrieve()) {
             throw new Q_Exception_NotVerified(array('type' => 'mobile number'), 'mobileNumber');
         }
     }
     $minutes = Q_Config::get('Users', 'activation', 'expires', 60 * 24 * 7);
     $this->activationCode = strtolower(Q_Utils::unique(7));
     $this->activationCodeExpires = new Db_Expression("CURRENT_TIMESTAMP + INTERVAL {$minutes} MINUTE");
     $this->authCode = sha1(microtime() + mt_rand());
     $number = $this->number;
     if (substr($number, 0, 2) == '+1') {
         $number = substr($number, 2);
     }
     $link = 'Users/activate?p=1&code=' . urlencode($this->activationCode) . ' mobileNumber=' . urlencode($number);
     $unsubscribe = 'Users/unsubscribe?mobileNumber=' . urlencode($number);
     $communityName = Users::communityName();
     $communitySuffix = Users::communitySuffix();
     /**
      * @event Users/resend {before}
      * @param {string} user
      * @param {string} mobile
      */
     Q::event('Users/resend', compact('user', 'mobile', 'link', 'unsubscribe'), 'before');
     $this->save();
     $fields2 = array_merge($fields, array('user' => $user, 'mobile' => $this, 'app' => Q_Config::expect('Q', 'app'), 'communityName' => $communityName, 'communitySuffix' => $communitySuffix, 'baseUrl' => Q_Request::baseUrl(), 'link' => $link, 'unsubscribe' => $unsubscribe));
     $this->sendMessage($view, $fields2, $options);
     // may throw exception if badly configured
     /**
      * @event Users/resend {after}
      * @param {string} user
      * @param {string} mobile
      */
     Q::event('Users/resend', compact('user', 'mobile', 'communityName'), 'after');
 }
Beispiel #9
0
 function resendActivationMessage($subject = null, $view = null, $fields = array(), $options = array())
 {
     if (!isset($subject)) {
         $subject = Q_Config::get('Users', 'transactional', 'resend', 'subject', Q_Config::get('Users', 'transactional', 'activation', 'subject', 'Did you forget your passphrase?'));
     }
     if (!isset($view)) {
         $view = Q_Config::get('Users', 'transactional', 'resend', 'body', Q_Config::get('Users', 'transactional', 'activation', 'body', 'Users/email/activation.php'));
     }
     if (!isset($options['html'])) {
         $options['html'] = true;
     }
     $user = $this->get('user', null);
     if (!$user) {
         $user = new Users_User();
         $user->id = $this->userId;
         if (!$user->retrieve()) {
             throw new Q_Exception_NotVerified(array('type' => 'email address'), 'emailAddress');
         }
     }
     $minutes = Q_Config::get('Users', 'activation', 'expires', 60 * 24 * 7);
     $this->activationCode = strtolower(Q_Utils::unique(7));
     $this->activationCodeExpires = new Db_Expression("CURRENT_TIMESTAMP + INTERVAL {$minutes} MINUTE");
     $this->authCode = sha1(microtime() + mt_rand());
     $link = 'Users/activate?p=1&code=' . urlencode($this->activationCode) . ' emailAddress=' . urlencode($this->address);
     $unsubscribe = 'Users/unsubscribe?' . http_build_query(array('authCode' => $this->authCode, 'emailAddress' => $this->address));
     $communityName = Users::communityName();
     $communitySuffix = Users::communitySuffix();
     /**
      * @event Users/resend {before}
      * @param {string} user
      * @param {string} email
      */
     Q::event('Users/resend', compact('user', 'email', 'link', 'unsubscribe'), 'before');
     $this->save();
     $email = $this;
     $fields2 = array_merge($fields, array('user' => $user, 'email' => $this, 'app' => Q_Config::expect('Q', 'app'), 'communityName' => $communityName, 'communitySuffix' => $communitySuffix, 'baseUrl' => Q_Request::baseUrl(), 'link' => $link, 'unsubscribe' => $unsubscribe));
     $this->sendMessage($subject, $view, $fields2, $options);
     // may throw exception if badly configured
     /**
      * @event Users/resend {after}
      * @param {string} user
      * @param {string} email
      */
     Q::event('Users/resend', compact('user', 'email'), 'after');
 }
Beispiel #10
0
 /**
  * Starts the process of adding a mobile to a saved user object.
  * Also modifies and saves this user object back to the database.
  * @method addMobile
  * @param {string} $mobileNumber
  *  The mobile number to add.
  * @param {string} [$activationMessageView=null]
  *  The view to use for the body of the activation message to send.
  * @param {array} [$fields=array()]
  *  An array of additional fields to pass to the mobile view.
  * @param {array} [$options=array()] Array of options. Can include:
  * @param {string} [$options.delay] A delay, in milliseconds, to wait until sending email. Only works if Node server is listening.
  * @param {string} [$options.activation] The key under "Users"/"transactional" config to use for getting activation messages by default. Set to false to skip sending the activation message for some reason.
  * @return {boolean}
  *  Returns true on success.
  *  Returns false if this mobile number is already verified for this user.
  * @throws {Q_Exception_WrongValue}
  *  If the mobile number is in an invalid format, this is thrown.
  * @throws {Users_Exception_AlreadyVerified}
  *  If the mobile number already exists and has been verified for
  *  another user, then this exception is thrown.
  */
 function addMobile($mobileNumber, $activationMessageView = null, array $fields = array(), array $options = array())
 {
     if (!Q_Valid::phone($mobileNumber, $normalized)) {
         throw new Q_Exception_WrongValue(array('field' => 'Mobile phone', 'range' => 'a valid number'), 'mobileNumber');
     }
     $mobile = new Users_Mobile();
     $mobile->number = $normalized;
     if ($mobile->retrieve('*', array('ignoreCache' => true)) and $mobile->state !== 'unverified') {
         if ($mobile->userId === $this->id) {
             $mobile->set('user', $this);
             return $mobile;
         }
         // Otherwise, say it's verified for another user,
         // even if it unsubscribed or was suspended.
         throw new Users_Exception_AlreadyVerified(array('key' => 'mobile number', 'userId' => $mobile->userId), 'mobileNumber');
     }
     $user = $this;
     // If we are here, then the mobile record either
     // doesn't exist, or hasn't been verified yet.
     // In either event, update the record in the database,
     // and re-send the mobile.
     $minutes = Q_Config::get('Users', 'activation', 'expires', 60 * 24 * 7);
     $mobile->state = 'unverified';
     $mobile->userId = $this->id;
     $mobile->activationCode = strtolower(Q_Utils::unique(7));
     $mobile->activationCodeExpires = new Db_Expression("CURRENT_TIMESTAMP + INTERVAL {$minutes} MINUTE");
     $number = $mobile->number;
     if (substr($number, 0, 2) == '+1') {
         $number = substr($number, 2);
     }
     $mobile->authCode = sha1(microtime() + mt_rand());
     $link = 'Users/activate?code=' . urlencode($mobile->activationCode) . ' mobileNumber=' . urlencode($number);
     $communityName = Users::communityName();
     $communitySuffix = Users::communitySuffix();
     /**
      * @event Users/addIdentifier {before}
      * @param {string} user
      * @param {string} mobile
      */
     Q::event('Users/addIdentifier', compact('user', 'mobile', 'link'), 'before');
     $mobile->save();
     $this->mobileNumberPending = $normalized;
     $this->save();
     if ($activation = Q::ifset($options, 'activation', 'activation')) {
         if (!isset($activationMessageView)) {
             $activationMessageView = Q_Config::get('Users', 'transactional', $activation, 'sms', 'Users/sms/activation.php');
         }
         $fields2 = array_merge($fields, array('user' => $this, 'mobile' => $mobile, 'app' => Q_Config::expect('Q', 'app'), 'communityName' => $communityName, 'communitySuffix' => $communitySuffix, 'baseUrl' => Q_Request::baseUrl(), 'link' => $link));
         $mobile->sendMessage($activationMessageView, $fields2, $options);
     }
     Q_Response::removeNotice('Users/mobile');
     /**
      * @event Users/addIdentifier {after}
      * @param {string} user
      * @param {string} mobile
      */
     Q::event('Users/addIdentifier', compact('user', 'mobile', 'link'), 'after');
 }
function Assets_after_Assets_charge($params)
{
    $user = $payments = $amount = $currency = $charge = $adapter = $options = null;
    extract($params, EXTR_OVERWRITE);
    $description = 'a product or service';
    $stream = Q::ifset($options, 'stream', null);
    if ($stream) {
        $publisherId = $stream->publisherId;
        $publisher = Users_User::fetch($publisherId, true);
        if ($stream->type === 'Assets/subscription') {
            $plan = Streams::fetchOne($stream->getAttribute('planPublisherId'), $stream->getAttribute('planPublisherId'), $stream->getAttribute('planStreamName'), true);
            $months = $stream->getAttribute('months');
            $startDate = $stream->getAttribute('startDate');
            $endDate = $stream->getAttribute('endDate');
        }
        $description = $stream->title;
    } else {
        $publisherId = Users::communityId();
        $publisher = Users_User::fetch($publisherId, true);
    }
    if (isset($options['description'])) {
        $description = $options['description'];
    }
    $currencies = Q::json_decode(file_get_contents(ASSETS_PLUGIN_CONFIG_DIR . DS . 'currencies.json'), true);
    if (!isset($currencies['symbols'][$currency])) {
        throw new Q_Exception_BadValue(array('internal' => 'currency', 'problem' => 'no symbol found'), 'currency');
    }
    if (!isset($currencies['names'][$currency])) {
        throw new Q_Exception_BadValue(array('internal' => 'currency', 'problem' => 'no name found'), 'currency');
    }
    $symbol = $currencies['symbols'][$currency];
    $currencyName = $currencies['names'][$currency];
    $communityId = Users::communityId();
    $communityName = Users::communityName();
    $communitySuffix = Users::communitySuffix();
    $link = Q_Request::baseUrl('action.php') . "/Assets/payment?publisherId={$publisherId}&userId=" . $user->id;
    $fields = compact('user', 'publisher', 'publisherId', 'communityId', 'communityName', 'communitySuffix', 'description', 'subscription', 'stream', 'plan', 'currency', 'name', 'symbol', 'currencyName', 'amount', 'months', 'startDate', 'endDate', 'link');
    if ($user->emailAddress) {
        $email = new Users_Email();
        $email->address = $user->emailAddress;
        $email->retrieve(true);
        $emailSubject = Q_Config::get('Assets', 'transactional', 'charged', 'subject', false);
        $emailView = Q_Config::get('Assets', 'transactional', 'charged', 'body', false);
        if ($emailSubject !== false and $emailView) {
            $email->sendMessage($emailSubject, $emailView, $fields);
        }
    } else {
        if ($user->mobileNumber) {
            $mobile = new Users_Mobile();
            $mobile->number = $user->mobileNumber;
            $mobile->retrieve(true);
            if ($mobileView = Q_Config::get('Assets', 'transactional', 'charged', 'sms', false)) {
                $mobile->sendMessage($mobileView, $fields);
            }
        }
    }
    if ($publisher->emailAddress) {
        $email = new Users_Email();
        $email->address = $publisher->emailAddress;
        $email->retrieve(true);
        $emailSubject = Q_Config::get('Assets', 'transactional', 'charge', 'subject', false);
        $emailView = Q_Config::get('Assets', 'transactional', 'charge', 'body', false);
        if ($emailSubject !== false and $emailView) {
            $email->sendMessage($emailSubject, $emailView, $fields);
        }
    } else {
        if ($publisher->mobileNumber) {
            $mobile = new Users_Mobile();
            $mobile->number = $publisher->mobileNumber;
            $mobile->retrieve(true);
            if ($mobileView = Q_Config::get('Assets', 'transactional', 'charge', 'sms', false)) {
                $mobile->sendMessage($mobileView, $fields);
            }
        }
    }
}