예제 #1
0
function Streams_invite_validate()
{
    if (Q_Request::method() === 'PUT') {
        return;
    }
    if (Q_Request::method() !== 'GET') {
        Q_Valid::nonce(true);
    }
    $fields = array('publisherId', 'streamName');
    if (Q_Request::method() === 'POST') {
        if (Q_Valid::requireFields($fields)) {
            return;
        }
        foreach ($fields as $f) {
            if (strlen(trim($_REQUEST[$f])) === 0) {
                Q_Response::addError(new Q_Exception("{$f} can't be empty", $f));
            }
        }
    }
    if (isset($_REQUEST['fullName'])) {
        $length_min = Q_Config::get('Streams', 'inputs', 'fullName', 'lengthMin', 5);
        $length_max = Q_Config::get('Streams', 'inputs', 'fullName', 'lengthMax', 30);
        if (strlen($_REQUEST['fullName']) < $length_min) {
            throw new Q_Exception("A user's full name can't be that short.", 'fullName');
        }
        if (strlen($_REQUEST['fullName']) > $length_max) {
            throw new Q_Exception("A user's full name can't be that long.", 'fullName');
        }
    }
}
예제 #2
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'));
}
예제 #3
0
 /**
  * Adds a device to the system, after sending a test notification to it
  * @param {array} $device
  * @param {string} $device.userId
  * @param {string} $device.deviceId
  * @param {string} [$device.formFactor]
  * @param {string} [$device.platform]
  * @param {string} [$device.version]
  * @param {string} [$device.sessionId]
  * @param {boolean} [$device.sandbox]
  * @param {string} [$device.passphrase]
  * @param {boolean} [$skipNotification=false] if true, skips sending notification
  * @return {Users_Device}
  */
 static function add($device, $skipNotification = false)
 {
     Q_Valid::requireFields(array('userId', 'deviceId'), $device, true);
     $userId = $device['userId'];
     $deviceId = $device['deviceId'];
     if (!$skipNotification) {
         $app = Q::app();
         $sandbox = Q::ifset($device, 'sandbox', null);
         if (!isset($sandbox)) {
             $sandbox = Q_Config::get($app, "cordova", "ios", "sandbox", false);
         }
         $env = $sandbox ? ApnsPHP_Abstract::ENVIRONMENT_SANDBOX : ApnsPHP_Abstract::ENVIRONMENT_PRODUCTION;
         $s = $sandbox ? 'sandbox' : 'production';
         $cert = APP_LOCAL_DIR . DS . 'Users' . DS . 'certs' . DS . $app . DS . $s . DS . 'bundle.pem';
         $authority = USERS_PLUGIN_FILES_DIR . DS . 'Users' . DS . 'certs' . DS . 'EntrustRootCA.pem';
         $logger = new Users_ApnsPHP_Logger();
         $push = new ApnsPHP_Push($env, $cert);
         $push->setLogger($logger);
         $push->setRootCertificationAuthority($authority);
         if (isset($device['passphrase'])) {
             $push->setProviderCertificatePassphrase($device['passphrase']);
         }
         $push->connect();
         $message = new ApnsPHP_Message($deviceId);
         $message->setCustomIdentifier('Users_Device-adding');
         $message->setBadge(0);
         $message->setText(Q_Config::get($app, "cordova", "ios", "device", "text", "Notifications have been enabled"));
         $message->setCustomProperty('userId', $userId);
         $message->setExpiry(5);
         $push->add($message);
         $push->send();
         $push->disconnect();
         $errors = $push->getErrors();
         if (!empty($errors)) {
             $result = reset($errors);
             throw new Users_Exception_DeviceNotification($result['ERRORS'][0]);
         }
     }
     $sessionId = Q_Session::id();
     $user = Users::loggedInUser();
     $info = array_merge(Q_Request::userAgentInfo(), array('sessionId' => $sessionId, 'userId' => $user ? $user->id : null, 'deviceId' => null));
     $device2 = Q::take($device, $info);
     $d = new Users_Device($device2);
     $d->save(true);
     if ($sessionId) {
         $s = new Users_Session();
         $s->id = $sessionId;
         if (!$s->retrieve()) {
             $s->deviceId = $deviceId;
         }
     }
     $_SESSION['Users']['deviceId'] = $deviceId;
     $device2['Q/method'] = 'Users/device';
     Q_Utils::sendToNode($device2);
     return $d;
 }
예제 #4
0
/**
 * Lets the user search for streams they can relate a given stream to, and relate it
 * @class Streams relate
 * @constructor
 * @param {array} [$options] Override various options for this tool
 * @param {string} $publisherId publisher id of the stream to relate
 * @param {string} $streamName name of stream to relate
 * @param {string} [$communityId=Users::communityId()] id of the user publishing the streams to relate to
 * @param {array} [$types=Q_Config::expect('Streams','relate','types')] the types of streams the user can select
 * @param {array} [$typeNames] pairs of array($type => $typeName) to override names of the types, which would otherwise be taken from the types
 * @param {Boolean} [options.multiple=true] whether the user can select multiple types for the lookup
 * @param {boolean} [$relateFrom=false] if true, will relate FROM the user-selected stream TO the streamName instead
 * @param {string} [$types=Q_Config::expect('Streams','relate','types')] the types of streams the user can select
 * @param {Q.Event} [$options.onRelate] This event handler occurs when a stream is successfully related
 */
function Streams_relate_tool($options)
{
    Q_Valid::requireFields(array('publisherId', 'streamName'), $options, true);
    if (!isset($options['communityId'])) {
        $options['communityId'] = Users::communityId();
    }
    if (!isset($options['types'])) {
        $options['types'] = Q_Config::get('Streams', 'relate', 'types', array());
    }
    Q_Response::setToolOptions($options);
    return '';
}
예제 #5
0
function Users_user_response_users($params = array())
{
    $req = array_merge($_REQUEST, $params);
    Q_Valid::requireFields(array('userIds'), $req, true);
    $userIds = $req['userIds'];
    if (is_string($userIds)) {
        $userIds = explode(",", $userIds);
    }
    $fields = Q_Config::expect('Users', 'avatarFields');
    $users = Users_User::select($fields)->where(array('id' => $userIds))->fetchDbRows(null, null, 'id');
    return Q_Response::setSlot('users', Db::exportArray($users, array('asAvatar' => true)));
}
예제 #6
0
/**
 * Used by HTTP clients to start a subscription
 * @class HTTP Assets subscription
 * @method post
 * @param {array} $_REQUEST
 * @param {string} $_REQUEST.payments Required. Should be either "authnet" or "stripe"
 *  @param {String} $_REQUEST.planStreamName the name of the subscription plan's stream
 *  @param {String} [$_REQUEST.planPublisherId=Users::communityId()] the publisher of the subscription plan's stream
 *  @param {String} [$_REQUEST.token=null] if using stripe, pass the token here
 */
function Assets_subscription_post($params = array())
{
    $req = array_merge($_REQUEST, $params);
    Q_Valid::requireFields(array('payments'), $req, true);
    // to be safe, we only start subscriptions from existing plans
    $planPublisherId = Q::ifset($req, 'planPublisherId', Users::communityId());
    $plan = Streams::fetchOne($planPublisherId, $planPublisherId, $req['planStreamName'], true);
    // the currency will always be assumed to be "USD" for now
    // and the amount will always be assumed to be in dollars, for now
    $token = Q::ifset($req, 'token', null);
    $subscription = Assets::startSubscription($plan, $req['payments'], compact('token'));
    Q_Response::setSlot('subscription', $subscription);
}
예제 #7
0
/**
 * Adds contacts to the system. Fills the "contacts" slot.
 * @param {array} $_REQUEST
 * @param {string} $_REQUEST.label The label of the contact
 * @param {string} $_REQUEST.contactUserId The contactUserId of the contact
 * @param {string} [$_REQUEST.nickname] The nickname of the contact
 * @param {string} [$_REQUEST.userId=Users::loggedInUser(true)->id] You can override the user id, if another plugin adds a hook that allows you to do this
 */
function Users_contact_post($params = array())
{
    if (Q_Request::slotName('batch') or Q_Request::slotName('contacts')) {
        return;
    }
    $req = array_merge($_REQUEST, $params);
    Q_Valid::requireFields(array('label', 'contactUserId'), $req, true);
    $loggedInUserId = Users::loggedInUser(true)->id;
    $userId = Q::ifset($req, 'userId', $loggedInUserId);
    $contactUserId = $req['contactUserId'];
    $nickname = Q::ifset($req, 'nickname', null);
    $contacts = Users_Contact::addContact($userId, $req['label'], $contactUserId, $nickname);
    Q_Response::setSlot('contacts', Db::exportArray($contacts));
}
예제 #8
0
function Users_user_response_batch($params = array())
{
    $req = array_merge($_REQUEST, $params);
    Q_Valid::requireFields(array('batch'), $req, true);
    $batch = $req['batch'];
    $batch = json_decode($batch, true);
    if (!isset($batch)) {
        throw new Q_Exception_WrongValue(array('field' => 'batch', 'range' => '{userIds: [userId1, userId2, ...]}'));
    }
    Q_Valid::requireFields(array('userIds'), $batch, true);
    $userIds = $batch['userIds'];
    $users = Q::event('Users/user/response/users', compact('userIds'));
    $result = array();
    foreach ($userIds as $userId) {
        $result[] = array('slots' => array('user' => isset($users[$userId]) ? $users[$userId] : null));
    }
    Q_Response::setSlot('batch', $result);
}
예제 #9
0
function Users_contact_response_batch($params = array())
{
    $req = array_merge($_REQUEST, $params);
    Q_Valid::requireFields(array('batch'), $req, true);
    $batch = $req['batch'];
    $batch = json_decode($batch, true);
    if (!isset($batch)) {
        throw new Q_Exception_WrongValue(array('field' => 'batch', 'range' => '{userIds: [...], labels: [...], contactUserIds: [...]}'));
    }
    Q_Valid::requireFields(array('userIds', 'labels', 'contactUserIds'), $batch, true);
    $userIds = $batch['userIds'];
    $labels = $batch['labels'];
    $contactUserIds = $batch['contactUserIds'];
    $contacts = Q::event('Users/contact/response/contacts', compact('userIds', 'labels', 'contactUserIds'));
    $result = array();
    foreach ($contacts as $contact) {
        $result[] = array('slots' => array('contact' => $contact));
    }
    Q_Response::setSlot('batch', $result);
}
예제 #10
0
 /**
  * Make a one-time charge using the payments processor
  * @method charge
  * @param {double} $amount specify the amount (optional cents after the decimal point)
  * @param {string} [$currency='USD'] set the currency, which will affect the amount
  * @param {array} [$options=array()] Any additional options
  * @param {string} [$options.token=null] required unless the user is an existing customer
  * @param {string} [$options.description=null] description of the charge, to be sent to customer
  * @param {string} [$options.metadata=null] any additional metadata to store with the charge
  * @param {string} [$options.subscription=null] if this charge is related to a subscription stream
  * @param {string} [$options.subscription.publisherId]
  * @param {string} [$options.subscription.streamName]
  * @throws \Stripe\Error\Card
  * @return {string} The customerId of the Assets_Customer that was successfully charged
  */
 function charge($amount, $currency = 'USD', $options = array())
 {
     $options = array_merge($this->options, $options);
     Q_Valid::requireFields(array('secret', 'user'), $options, true);
     \Stripe\Stripe::setApiKey($options['secret']);
     $user = $options['user'];
     $customer = new Assets_Customer();
     $customer->userId = $user->id;
     $customer->payments = 'stripe';
     if (!$customer->retrieve()) {
         Q_Valid::requireFields(array('token'), $options, true);
         $sc = \Stripe\Customer::create(array("source" => $options['token']["id"], "description" => $options['user']->displayName()));
         $customer->customerId = $sc->id;
         $customer->save();
     }
     $params = array("amount" => $amount * 100, "currency" => $currency, "customer" => $customer->customerId);
     Q::take($options, array('description', 'metadata'), $params);
     \Stripe\Charge::create($params);
     // can throw some exception
     return $customer->customerId;
 }
예제 #11
0
 /**
  * Registers a user in the system.
  * @method register
  * @static
  * @param {string} $username The name of the user
  * @param {string|array} $identifier Can be an email address or mobile number. Or it could be an array of $type => $info
  * @param {string} [$identifier.identifier] an email address or phone number
  * @param {array} [$identifier.device] an array with keys "deviceId", "platform", "version"
  *   to store in the Users_Device table for sending notifications
  * @param {array|string} [$icon=array()] Array of filename => url pairs
  * @param {string} [$provider=null] Provider such as "facebook"
  * @param {array} [$options=array()] An array of options that could include:
  * @param {string} [$options.activation] The key under "Users"/"transactional" config to use for sending an activation message. Set to false to skip sending the activation message for some reason.
  * @return {Users_User}
  * @throws {Q_Exception_WrongType} If identifier is not e-mail or modile
  * @throws {Q_Exception} If user was already verified for someone else
  * @throws {Users_Exception_AlreadyVerified} If user was already verified
  * @throws {Users_Exception_UsernameExists} If username exists
  */
 static function register($username, $identifier, $icon = array(), $provider = null, $options = array())
 {
     if (is_array($provider)) {
         $options = $provider;
         $provider = null;
     }
     /**
      * @event Users/register {before}
      * @param {string} username
      * @param {string|array} identifier
      * @param {string} icon
      * @param {string} provider
      * @return {Users_User}
      */
     $return = Q::event('Users/register', compact('username', 'identifier', 'icon', 'provider', 'options'), 'before');
     if (isset($return)) {
         return $return;
     }
     $during = 'register';
     if (is_array($identifier)) {
         reset($identifier);
         switch (key($identifier)) {
             case 'device':
                 $fields = array('deviceId', 'platform', 'version');
                 Q_Valid::requireFields($fields, $identifier, true);
                 $device = $identifier;
                 if (isset($identifier['identifier'])) {
                     $identifier = $identifier['identifier'];
                 }
                 break;
             default:
                 throw new Q_Exception_WrongType(array('field' => 'identifier', 'type' => 'an array with entry named "device"'));
         }
     }
     if (Q_Valid::email($identifier, $emailAddress)) {
         $ui_identifier = $emailAddress;
         $key = 'email address';
         $type = 'email';
     } else {
         if (Q_Valid::phone($identifier, $mobileNumber)) {
             $key = 'mobile number';
             $ui_identifier = $mobileNumber;
             $type = 'mobile';
         } else {
             throw new Q_Exception_WrongType(array('field' => 'identifier', 'type' => 'email address or mobile number'), array('emailAddress', 'mobileNumber'));
         }
     }
     $user = false;
     if ($provider) {
         if ($provider != 'facebook') {
             throw new Q_Exception_WrongType(array('field' => 'provider', 'type' => '"facebook"'));
         }
         $facebook = Users::facebook();
         if ($facebook) {
             $uid = $facebook->getUser();
             try {
                 // authenticate (and possibly adopt) an existing provider user
                 // or insert a new user during this authentication
                 $user = Users::authenticate($provider, null, $authenticated, true);
             } catch (Exception $e) {
             }
             if ($user) {
                 // the user is also logged in
                 $adopted = true;
                 // Adopt this provider user
                 /**
                  * @event Users/adoptFutureUser {before}
                  * @param {Users_User} user
                  * @param {string} during
                  * @return {Users_User}
                  */
                 $ret = Q::event('Users/adoptFutureUser', compact('user', 'during'), 'before');
                 if ($ret) {
                     $user = $ret;
                 }
             }
         }
     }
     if (!$user) {
         $user = new Users_User();
         // the user we will save in the database
     }
     if (empty($adopted)) {
         // We will be inserting a new user into the database, so check if
         // this identifier was already verified for someone else.
         $ui = Users::identify($type, $ui_identifier);
         if ($ui) {
             throw new Users_Exception_AlreadyVerified(compact('key'), array('emailAddress', 'mobileNumber', 'identifier'));
         }
     }
     // Insert a new user into the database, or simply modify an existing (adopted) user
     $user->username = $username;
     if (!isset($user->signedUpWith) or $user->signedUpWith == 'none') {
         $user->signedUpWith = $type;
     }
     $user->icon = 'default';
     $user->passphraseHash = '';
     $url_parts = parse_url(Q_Request::baseUrl());
     if (isset($url_parts['host'])) {
         // By default, the user's url would be this:
         $user->url = $username ? "http://{$username}." . $url_parts['host'] : "";
     }
     /**
      * @event Users/insertUser {before}
      * @param {string} during
      * @param {Users_User} user
      */
     Q::event('Users/insertUser', compact('user', 'during'), 'before');
     $user->save();
     // sets the user's id
     /**
      * @event Users/insertUser {after}
      * @param {string} during
      * @param {Users_User} user
      */
     Q::event('Users/insertUser', compact('user', 'during'), 'after');
     $sizes = Q_Config::expect('Users', 'icon', 'sizes');
     sort($sizes);
     if (empty($icon)) {
         switch ($provider) {
             case 'facebook':
                 // let's get this user's icon on facebook
                 if (empty($uid)) {
                     break;
                 }
                 $icon = array();
                 foreach ($sizes as $size) {
                     $icon["{$size}.png"] = "https://graph.facebook.com/{$uid}/picture?width={$size}&height={$size}";
                 }
                 break;
         }
     } else {
         // Import the user's icon and save it
         if (is_string($icon)) {
             // assume it's from gravatar
             $iconString = $icon;
             $icon = array();
             foreach ($sizes as $size) {
                 $icon["{$size}.png"] = "{$iconString}&s={$size}";
             }
         } else {
             // locally generated icons
             $hash = md5(strtolower(trim($identifier)));
             $icon = array();
             foreach ($sizes as $size) {
                 $icon["{$size}.png"] = array('hash' => $hash, 'size' => $size);
             }
         }
     }
     if (!Q_Config::get('Users', 'register', 'icon', 'leaveDefault', false)) {
         self::importIcon($user, $icon);
         $user->save();
     }
     if (empty($user->emailAddress) and empty($user->mobileNumber)) {
         // Add an email address or mobile number to the user, that they'll have to verify
         try {
             $activation = Q::ifset($options, 'activation', 'activation');
             if ($activation) {
                 $subject = Q_Config::get('Users', 'transactional', $activation, "subject", null);
                 $body = Q_Config::get('Users', 'transactional', $activation, "body", null);
             } else {
                 $subject = $body = null;
             }
             if ($type === 'email') {
                 $user->addEmail($identifier, $subject, $body, array(), $options);
             } else {
                 if ($type === 'mobile') {
                     $p = $options;
                     if ($delay = Q_Config::get('Users', 'register', 'delaySms', 0)) {
                         $p['delay'] = $delay;
                     }
                     $sms = Q_Config::get('Users', 'transactional', $activation, "sms", null);
                     $user->addMobile($mobileNumber, $sms, array(), $p);
                 }
             }
         } catch (Exception $e) {
             // The activation message could not be sent, so remove this user
             // from the database. This way, this username will be
             // back on the market.
             $user->remove();
             throw $e;
         }
     }
     if (!empty($device)) {
         $device['userId'] = $user->id;
         Users_Device::add($device);
     }
     /**
      * @event Users/register {after}
      * @param {string} username
      * @param {string|array} identifier
      * @param {string} icon
      * @param {Users_User} user
      * @param {string} provider
      * @return {Users_User}
      */
     $return = Q::event('Users/register', compact('username', 'identifier', 'icon', 'user', 'provider', 'options', 'device'), 'after');
     return $user;
 }