Beispiel #1
0
 function post()
 {
     if ($_POST['room_name']) {
         $room = strip_tags(trim($_POST['room_name']));
     }
     if (!$room || !local_channel()) {
         return;
     }
     $channel = \App::get_channel();
     if ($_POST['action'] === 'drop') {
         logger('delete chatroom');
         Zlib\Chatroom::destroy($channel, array('cr_name' => $room));
         goaway(z_root() . '/chat/' . $channel['channel_address']);
     }
     $acl = new \Zotlabs\Access\AccessList($channel);
     $acl->set_from_array($_REQUEST);
     $arr = $acl->get();
     $arr['name'] = $room;
     $arr['expire'] = intval($_POST['chat_expire']);
     if (intval($arr['expire']) < 0) {
         $arr['expire'] = 0;
     }
     Zlib\Chatroom::create($channel, $arr);
     $x = q("select * from chatroom where cr_name = '%s' and cr_uid = %d limit 1", dbesc($room), intval(local_channel()));
     build_sync_packet(0, array('chatroom' => $x));
     if ($x) {
         goaway(z_root() . '/chat/' . $channel['channel_address'] . '/' . $x[0]['cr_id']);
     }
     // that failed. Try again perhaps?
     goaway(z_root() . '/chat/' . $channel['channel_address'] . '/new');
 }
/**
 *
 * @param object &$a
 */
function filestorage_post(&$a)
{
    $channel_id = x($_POST, 'uid') ? intval($_POST['uid']) : 0;
    if (!$channel_id || !local_channel() || $channel_id != local_channel()) {
        notice(t('Permission denied.') . EOL);
        return;
    }
    $recurse = x($_POST, 'recurse') ? intval($_POST['recurse']) : 0;
    $resource = x($_POST, 'filehash') ? notags($_POST['filehash']) : '';
    $notify = x($_POST, 'notify') ? intval($_POST['notify']) : 0;
    if (!$resource) {
        notice(t('Item not found.') . EOL);
        return;
    }
    $channel = App::get_channel();
    $acl = new Zotlabs\Access\AccessList($channel);
    $acl->set_from_array($_REQUEST);
    $x = $acl->get();
    $cloudPath = get_parent_cloudpath($channel_id, $channel['channel_address'], $resource);
    //get the object before permissions change so we can catch eventual former allowed members
    $object = get_file_activity_object($channel_id, $resource, $cloudPath);
    attach_change_permissions($channel_id, $resource, $x['allow_cid'], $x['allow_gid'], $x['deny_cid'], $x['deny_gid'], $recurse);
    file_activity($channel_id, $object, $x['allow_cid'], $x['allow_gid'], $x['deny_cid'], $x['deny_gid'], 'post', $notify);
    goaway($cloudPath);
}
Beispiel #3
0
function thing_init(&$a)
{
    if (!local_channel()) {
        return;
    }
    $channel = App::get_channel();
    $term_hash = $_REQUEST['term_hash'] ? $_REQUEST['term_hash'] : '';
    $name = escape_tags($_REQUEST['term']);
    $verb = escape_tags($_REQUEST['verb']);
    $activity = intval($_REQUEST['activity']);
    $profile_guid = escape_tags($_REQUEST['profile_assign']);
    $url = $_REQUEST['link'];
    $photo = $_REQUEST['img'];
    $hash = random_string();
    $verbs = obj_verbs();
    /**
     * verbs: [0] = first person singular, e.g. "I want", [1] = 3rd person singular, e.g. "Bill wants" 
     * We use the first person form when creating an activity, but the third person for use in activities
     * @FIXME There is no accounting for verb gender for languages where this is significant. We may eventually
     * require obj_verbs() to provide full conjugations and specify which form to use in the $_REQUEST params to this module.
     */
    $translated_verb = $verbs[$verb][1];
    /*
     * The site administrator can do things that normals cannot.
     * This is restricted because it will likely cause
     * an activitystreams protocol violation and the activity might
     * choke in some other network and result in unnecessary 
     * support requests. It isn't because we're trying to be heavy-handed
     * about what you can and can't do. 
     */
    if (!$translated_verb) {
        if (is_site_admin()) {
            $translated_verb = $verb;
        }
    }
    /*
     * Things, objects: We do not provide definite (a, an) or indefinite (the) articles or singular/plural designators
     * That needs to be specified in your thing. e.g. Mike has "a carrot", Greg wants "balls", Bob likes "the Boston Red Sox".  
     */
    /*
     * Future work on this module might produce more complex activities with targets, e.g. Phillip likes Karen's moustache
     * and to describe other non-thing objects like channels, such as Karl wants Susan - where Susan represents a channel profile.
     */
    if (!$name || !$translated_verb) {
        return;
    }
    $acl = new Zotlabs\Access\AccessList($channel);
    if (array_key_exists('contact_allow', $_REQUEST) || array_key_exists('group_allow', $_REQUEST) || array_key_exists('contact_deny', $_REQUEST) || array_key_exists('group_deny', $_REQUEST)) {
        $acl->set_from_array($_REQUEST);
    }
    $x = $acl->get();
    if ($term_hash) {
        $t = q("select * from obj where obj_obj = '%s' and obj_channel = %d limit 1", dbesc($term_hash), intval(local_channel()));
        if (!$t) {
            notice(t('Item not found.') . EOL);
            return;
        }
        $orig_record = $t[0];
        if ($photo != $orig_record['obj_imgurl']) {
            $arr = import_xchan_photo($photo, get_observer_hash(), true);
            $local_photo = $arr[0];
            $local_photo_type = $arr[3];
        } else {
            $local_photo = $orig_record['obj_imgurl'];
        }
        $r = q("update obj set obj_term = '%s', obj_url = '%s', obj_imgurl = '%s', obj_edited = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where obj_obj = '%s' and obj_channel = %d ", dbesc($name), dbesc($url ? $url : z_root() . '/thing/' . $term_hash), dbesc($local_photo), dbesc(datetime_convert()), dbesc($x['allow_cid']), dbesc($x['allow_gid']), dbesc($x['deny_cid']), dbesc($x['deny_gid']), dbesc($term_hash), intval(local_channel()));
        info(t('Thing updated') . EOL);
        $r = q("select * from obj where obj_channel = %d and obj_obj = '%s' limit 1", intval(local_channel()), dbesc($term_hash));
        if ($r) {
            build_sync_packet(0, array('obj' => $r));
        }
        return;
    }
    $sql = $profile_guid ? " and profile_guid = '" . dbesc($profile_guid) . "' " : " and is_default = 1 ";
    $p = q("select profile_guid, is_default from profile where uid = %d {$sql} limit 1", intval(local_channel()));
    if ($p) {
        $profile = $p[0];
    } else {
        return;
    }
    $local_photo = null;
    if ($photo) {
        $arr = import_xchan_photo($photo, get_observer_hash(), true);
        $local_photo = $arr[0];
        $local_photo_type = $arr[3];
    }
    $created = datetime_convert();
    $url = $url ? $url : z_root() . '/thing/' . $hash;
    $r = q("insert into obj ( obj_page, obj_verb, obj_type, obj_channel, obj_obj, obj_term, obj_url, obj_imgurl, obj_created, obj_edited, allow_cid, allow_gid, deny_cid, deny_gid ) values ('%s','%s', %d, %d, '%s','%s','%s','%s','%s','%s','%s','%s','%s','%s') ", dbesc($profile['profile_guid']), dbesc($verb), intval(TERM_OBJ_THING), intval(local_channel()), dbesc($hash), dbesc($name), dbesc($url), dbesc($photo ? $local_photo : ''), dbesc($created), dbesc($created), dbesc($x['allow_cid']), dbesc($x['allow_gid']), dbesc($x['deny_cid']), dbesc($x['deny_gid']));
    if (!$r) {
        notice(t('Object store: failed'));
        return;
    }
    info(t('Thing added'));
    $r = q("select * from obj where obj_channel = %d and obj_obj = '%s' limit 1", intval(local_channel()), dbesc($hash));
    if ($r) {
        build_sync_packet(0, array('obj' => $r));
    }
    if ($activity) {
        $arr = array();
        $links = array(array('rel' => 'alternate', 'type' => 'text/html', 'href' => $url));
        if ($local_photo) {
            $links[] = array('rel' => 'photo', 'type' => $local_photo_type, 'href' => $local_photo);
        }
        $objtype = ACTIVITY_OBJ_THING;
        $obj = json_encode(array('type' => $objtype, 'id' => $url, 'link' => $links, 'title' => $name, 'content' => $name));
        $bodyverb = str_replace('OBJ: ', '', t('OBJ: %1$s %2$s %3$s'));
        $arr['owner_xchan'] = $channel['channel_hash'];
        $arr['author_xchan'] = $channel['channel_hash'];
        $arr['item_origin'] = 1;
        $arr['item_wall'] = 1;
        $arr['item_thread_top'] = 1;
        $ulink = '[zrl=' . $channel['xchan_url'] . ']' . $channel['channel_name'] . '[/zrl]';
        $plink = '[zrl=' . $url . ']' . $name . '[/zrl]';
        $arr['body'] = sprintf($bodyverb, $ulink, $translated_verb, $plink);
        if ($local_photo) {
            $arr['body'] .= "\n\n[zmg]" . $local_photo . "[/zmg]";
        }
        $arr['verb'] = $verb;
        $arr['obj_type'] = $objtype;
        $arr['object'] = $obj;
        if (!$profile['is_default']) {
            $arr['item_private'] = true;
            $str = '';
            $r = q("select abook_xchan from abook where abook_channel = %d and abook_profile = '%s'", intval(local_channel()), dbesc($profile_guid));
            if ($r) {
                $arr['allow_cid'] = '';
                foreach ($r as $rr) {
                    $arr['allow_cid'] .= '<' . $rr['abook_xchan'] . '>';
                }
            } else {
                $arr['allow_cid'] = '<' . get_observer_hash() . '>';
            }
        }
        $ret = post_activity_item($arr);
    }
}
Beispiel #4
0
 function post()
 {
     $channel = \App::get_channel();
     check_form_security_token_redirectOnErr('/settings', 'settings');
     call_hooks('settings_post', $_POST);
     $set_perms = '';
     $role = x($_POST, 'permissions_role') ? notags(trim($_POST['permissions_role'])) : '';
     $oldrole = get_pconfig(local_channel(), 'system', 'permissions_role');
     if ($role != $oldrole || $role === 'custom') {
         if ($role === 'custom') {
             $hide_presence = x($_POST, 'hide_presence') && intval($_POST['hide_presence']) == 1 ? 1 : 0;
             $publish = x($_POST, 'profile_in_directory') && intval($_POST['profile_in_directory']) == 1 ? 1 : 0;
             $def_group = x($_POST, 'group-selection') ? notags(trim($_POST['group-selection'])) : '';
             $r = q("update channel set channel_default_group = '%s' where channel_id = %d", dbesc($def_group), intval(local_channel()));
             $global_perms = \Zotlabs\Access\Permissions::Perms();
             foreach ($global_perms as $k => $v) {
                 \Zotlabs\Access\PermissionLimits::Set(local_channel(), $k, intval($_POST[$k]));
             }
             $acl = new \Zotlabs\Access\AccessList($channel);
             $acl->set_from_array($_POST);
             $x = $acl->get();
             $r = q("update channel set channel_allow_cid = '%s', channel_allow_gid = '%s', \n\t\t\t\t\tchannel_deny_cid = '%s', channel_deny_gid = '%s' where channel_id = %d", dbesc($x['allow_cid']), dbesc($x['allow_gid']), dbesc($x['deny_cid']), dbesc($x['deny_gid']), intval(local_channel()));
         } else {
             $role_permissions = \Zotlabs\Access\PermissionRoles::role_perms($_POST['permissions_role']);
             if (!$role_permissions) {
                 notice('Permissions category could not be found.');
                 return;
             }
             $hide_presence = 1 - intval($role_permissions['online']);
             if ($role_permissions['default_collection']) {
                 $r = q("select hash from groups where uid = %d and gname = '%s' limit 1", intval(local_channel()), dbesc(t('Friends')));
                 if (!$r) {
                     require_once 'include/group.php';
                     group_add(local_channel(), t('Friends'));
                     group_add_member(local_channel(), t('Friends'), $channel['channel_hash']);
                     $r = q("select hash from groups where uid = %d and gname = '%s' limit 1", intval(local_channel()), dbesc(t('Friends')));
                 }
                 if ($r) {
                     q("update channel set channel_default_group = '%s', channel_allow_gid = '%s', channel_allow_cid = '', channel_deny_gid = '', channel_deny_cid = '' where channel_id = %d", dbesc($r[0]['hash']), dbesc('<' . $r[0]['hash'] . '>'), intval(local_channel()));
                 } else {
                     notice(sprintf('Default privacy group \'%s\' not found. Please create and re-submit permission change.', t('Friends')) . EOL);
                     return;
                 }
             } else {
                 q("update channel set channel_default_group = '', channel_allow_gid = '', channel_allow_cid = '', channel_deny_gid = '', \n\t\t\t\t\t\tchannel_deny_cid = '' where channel_id = %d", intval(local_channel()));
             }
             $x = \Zotlabs\Access\Permissions::FilledPerms($role_permissions['perms_connect']);
             foreach ($x as $k => $v) {
                 set_abconfig(local_channel(), $channel['channel_hash'], 'my_perms', $k, $v);
                 if ($role_permissions['perms_auto']) {
                     set_pconfig(local_channel(), 'autoperms', $k, $v);
                 } else {
                     del_pconfig(local_channel(), 'autoperms', $k);
                 }
             }
             if ($role_permissions['limits']) {
                 foreach ($role_permissions['limits'] as $k => $v) {
                     \Zotlabs\Access\PermissionLimits::Set(local_channel(), $k, $v);
                 }
             }
             if (array_key_exists('directory_publish', $role_permissions)) {
                 $publish = intval($role_permissions['directory_publish']);
             }
         }
         set_pconfig(local_channel(), 'system', 'hide_online_status', $hide_presence);
         set_pconfig(local_channel(), 'system', 'permissions_role', $role);
     }
     $username = x($_POST, 'username') ? notags(trim($_POST['username'])) : '';
     $timezone = x($_POST, 'timezone_select') ? notags(trim($_POST['timezone_select'])) : '';
     $defloc = x($_POST, 'defloc') ? notags(trim($_POST['defloc'])) : '';
     $openid = x($_POST, 'openid_url') ? notags(trim($_POST['openid_url'])) : '';
     $maxreq = x($_POST, 'maxreq') ? intval($_POST['maxreq']) : 0;
     $expire = x($_POST, 'expire') ? intval($_POST['expire']) : 0;
     $evdays = x($_POST, 'evdays') ? intval($_POST['evdays']) : 3;
     $photo_path = x($_POST, 'photo_path') ? escape_tags(trim($_POST['photo_path'])) : '';
     $attach_path = x($_POST, 'attach_path') ? escape_tags(trim($_POST['attach_path'])) : '';
     $channel_menu = x($_POST['channel_menu']) ? htmlspecialchars_decode(trim($_POST['channel_menu']), ENT_QUOTES) : '';
     $expire_items = x($_POST, 'expire_items') ? intval($_POST['expire_items']) : 0;
     $expire_starred = x($_POST, 'expire_starred') ? intval($_POST['expire_starred']) : 0;
     $expire_photos = x($_POST, 'expire_photos') ? intval($_POST['expire_photos']) : 0;
     $expire_network_only = x($_POST, 'expire_network_only') ? intval($_POST['expire_network_only']) : 0;
     $allow_location = x($_POST, 'allow_location') && intval($_POST['allow_location']) == 1 ? 1 : 0;
     $blocktags = x($_POST, 'blocktags') && intval($_POST['blocktags']) == 1 ? 0 : 1;
     // this setting is inverted!
     $unkmail = x($_POST, 'unkmail') && intval($_POST['unkmail']) == 1 ? 1 : 0;
     $cntunkmail = x($_POST, 'cntunkmail') ? intval($_POST['cntunkmail']) : 0;
     $suggestme = x($_POST, 'suggestme') ? intval($_POST['suggestme']) : 0;
     $post_newfriend = $_POST['post_newfriend'] == 1 ? 1 : 0;
     $post_joingroup = $_POST['post_joingroup'] == 1 ? 1 : 0;
     $post_profilechange = $_POST['post_profilechange'] == 1 ? 1 : 0;
     $adult = $_POST['adult'] == 1 ? 1 : 0;
     $cal_first_day = x($_POST, 'first_day') && intval($_POST['first_day']) == 1 ? 1 : 0;
     $pageflags = $channel['channel_pageflags'];
     $existing_adult = $pageflags & PAGE_ADULT ? 1 : 0;
     if ($adult != $existing_adult) {
         $pageflags = $pageflags ^ PAGE_ADULT;
     }
     $notify = 0;
     if (x($_POST, 'notify1')) {
         $notify += intval($_POST['notify1']);
     }
     if (x($_POST, 'notify2')) {
         $notify += intval($_POST['notify2']);
     }
     if (x($_POST, 'notify3')) {
         $notify += intval($_POST['notify3']);
     }
     if (x($_POST, 'notify4')) {
         $notify += intval($_POST['notify4']);
     }
     if (x($_POST, 'notify5')) {
         $notify += intval($_POST['notify5']);
     }
     if (x($_POST, 'notify6')) {
         $notify += intval($_POST['notify6']);
     }
     if (x($_POST, 'notify7')) {
         $notify += intval($_POST['notify7']);
     }
     if (x($_POST, 'notify8')) {
         $notify += intval($_POST['notify8']);
     }
     $vnotify = 0;
     if (x($_POST, 'vnotify1')) {
         $vnotify += intval($_POST['vnotify1']);
     }
     if (x($_POST, 'vnotify2')) {
         $vnotify += intval($_POST['vnotify2']);
     }
     if (x($_POST, 'vnotify3')) {
         $vnotify += intval($_POST['vnotify3']);
     }
     if (x($_POST, 'vnotify4')) {
         $vnotify += intval($_POST['vnotify4']);
     }
     if (x($_POST, 'vnotify5')) {
         $vnotify += intval($_POST['vnotify5']);
     }
     if (x($_POST, 'vnotify6')) {
         $vnotify += intval($_POST['vnotify6']);
     }
     if (x($_POST, 'vnotify7')) {
         $vnotify += intval($_POST['vnotify7']);
     }
     if (x($_POST, 'vnotify8')) {
         $vnotify += intval($_POST['vnotify8']);
     }
     if (x($_POST, 'vnotify9')) {
         $vnotify += intval($_POST['vnotify9']);
     }
     if (x($_POST, 'vnotify10')) {
         $vnotify += intval($_POST['vnotify10']);
     }
     if (x($_POST, 'vnotify11')) {
         $vnotify += intval($_POST['vnotify11']);
     }
     $always_show_in_notices = x($_POST, 'always_show_in_notices') ? 1 : 0;
     $err = '';
     $name_change = false;
     if ($username != $channel['channel_name']) {
         $name_change = true;
         require_once 'include/channel.php';
         $err = validate_channelname($username);
         if ($err) {
             notice($err);
             return;
         }
     }
     if ($timezone != $channel['channel_timezone']) {
         if (strlen($timezone)) {
             date_default_timezone_set($timezone);
         }
     }
     set_pconfig(local_channel(), 'system', 'use_browser_location', $allow_location);
     set_pconfig(local_channel(), 'system', 'suggestme', $suggestme);
     set_pconfig(local_channel(), 'system', 'post_newfriend', $post_newfriend);
     set_pconfig(local_channel(), 'system', 'post_joingroup', $post_joingroup);
     set_pconfig(local_channel(), 'system', 'post_profilechange', $post_profilechange);
     set_pconfig(local_channel(), 'system', 'blocktags', $blocktags);
     set_pconfig(local_channel(), 'system', 'channel_menu', $channel_menu);
     set_pconfig(local_channel(), 'system', 'vnotify', $vnotify);
     set_pconfig(local_channel(), 'system', 'always_show_in_notices', $always_show_in_notices);
     set_pconfig(local_channel(), 'system', 'evdays', $evdays);
     set_pconfig(local_channel(), 'system', 'photo_path', $photo_path);
     set_pconfig(local_channel(), 'system', 'attach_path', $attach_path);
     set_pconfig(local_channel(), 'system', 'cal_first_day', $cal_first_day);
     $r = q("update channel set channel_name = '%s', channel_pageflags = %d, channel_timezone = '%s', channel_location = '%s', channel_notifyflags = %d, channel_max_anon_mail = %d, channel_max_friend_req = %d, channel_expire_days = %d {$set_perms} where channel_id = %d", dbesc($username), intval($pageflags), dbesc($timezone), dbesc($defloc), intval($notify), intval($unkmail), intval($maxreq), intval($expire), intval(local_channel()));
     if ($r) {
         info(t('Settings updated.') . EOL);
     }
     if (!is_null($publish)) {
         $r = q("UPDATE profile SET publish = %d WHERE is_default = 1 AND uid = %d", intval($publish), intval(local_channel()));
     }
     if ($name_change) {
         $r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s' where xchan_hash = '%s'", dbesc($username), dbesc(datetime_convert()), dbesc($channel['channel_hash']));
         $r = q("update profile set fullname = '%s' where uid = %d and is_default = 1", dbesc($username), intval($channel['channel_id']));
     }
     \Zotlabs\Daemon\Master::Summon(array('Directory', local_channel()));
     build_sync_packet();
     if ($email_changed && \App::$config['system']['register_policy'] == REGISTER_VERIFY) {
         // FIXME - set to un-verified, blocked and redirect to logout
         // Why? Are we verifying people or email addresses?
     }
     goaway(z_root() . '/settings');
     return;
     // NOTREACHED
 }
Beispiel #5
0
 function post()
 {
     if (!local_channel()) {
         return;
     }
     if ($_SESSION['delegate']) {
         return;
     }
     $channel = \App::get_channel();
     logger('mod_settings: ' . print_r($_REQUEST, true));
     if (argc() > 1 && argv(1) === 'oauth' && x($_POST, 'remove')) {
         check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth');
         $key = $_POST['remove'];
         q("DELETE FROM tokens WHERE id='%s' AND uid=%d", dbesc($key), local_channel());
         goaway(z_root() . "/settings/oauth/");
         return;
     }
     if (argc() > 2 && argv(1) === 'oauth' && (argv(2) === 'edit' || argv(2) === 'add') && x($_POST, 'submit')) {
         check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth');
         $name = x($_POST, 'name') ? $_POST['name'] : '';
         $key = x($_POST, 'key') ? $_POST['key'] : '';
         $secret = x($_POST, 'secret') ? $_POST['secret'] : '';
         $redirect = x($_POST, 'redirect') ? $_POST['redirect'] : '';
         $icon = x($_POST, 'icon') ? $_POST['icon'] : '';
         $ok = true;
         if ($name == '') {
             $ok = false;
             notice(t('Name is required') . EOL);
         }
         if ($key == '' || $secret == '') {
             $ok = false;
             notice(t('Key and Secret are required') . EOL);
         }
         if ($ok) {
             if ($_POST['submit'] == t("Update")) {
                 $r = q("UPDATE clients SET\n\t\t\t\t\t\t\t\tclient_id='%s',\n\t\t\t\t\t\t\t\tpw='%s',\n\t\t\t\t\t\t\t\tclname='%s',\n\t\t\t\t\t\t\t\tredirect_uri='%s',\n\t\t\t\t\t\t\t\ticon='%s',\n\t\t\t\t\t\t\t\tuid=%d\n\t\t\t\t\t\t\tWHERE client_id='%s'", dbesc($key), dbesc($secret), dbesc($name), dbesc($redirect), dbesc($icon), intval(local_channel()), dbesc($key));
             } else {
                 $r = q("INSERT INTO clients (client_id, pw, clname, redirect_uri, icon, uid)\n\t\t\t\t\t\tVALUES ('%s','%s','%s','%s','%s',%d)", dbesc($key), dbesc($secret), dbesc($name), dbesc($redirect), dbesc($icon), intval(local_channel()));
                 $r = q("INSERT INTO xperm (xp_client, xp_channel, xp_perm) VALUES ('%s', %d, '%s') ", dbesc($key), intval(local_channel()), dbesc('all'));
             }
         }
         goaway(z_root() . "/settings/oauth/");
         return;
     }
     if (argc() > 1 && argv(1) == 'featured') {
         check_form_security_token_redirectOnErr('/settings/featured', 'settings_featured');
         call_hooks('feature_settings_post', $_POST);
         build_sync_packet();
         return;
     }
     if (argc() > 1 && argv(1) == 'tokens') {
         check_form_security_token_redirectOnErr('/settings/tokens', 'settings_tokens');
         $token_errs = 0;
         if (array_key_exists('token', $_POST)) {
             $atoken_id = $_POST['atoken_id'] ? intval($_POST['atoken_id']) : 0;
             $name = trim(escape_tags($_POST['name']));
             $token = trim($_POST['token']);
             if (!$name || !$token) {
                 $token_errs++;
             }
             if (trim($_POST['expires'])) {
                 $expires = datetime_convert(date_default_timezone_get(), 'UTC', $_POST['expires']);
             } else {
                 $expires = NULL_DATE;
             }
             $max_atokens = service_class_fetch(local_channel(), 'access_tokens');
             if ($max_atokens) {
                 $r = q("select count(atoken_id) as total where atoken_uid = %d", intval(local_channel()));
                 if ($r && intval($r[0]['total']) >= $max_tokens) {
                     notice(sprintf(t('This channel is limited to %d tokens'), $max_tokens) . EOL);
                     return;
                 }
             }
         }
         if ($token_errs) {
             notice(t('Name and Password are required.') . EOL);
             return;
         }
         if ($atoken_id) {
             $r = q("update atoken set atoken_name = '%s', atoken_token = '%s' atoken_expires = '%s' \n\t\t\t\t\twhere atoken_id = %d and atoken_uid = %d", dbesc($name), dbesc($token), dbesc($expires), intval($atoken_id), intval($channel['channel_id']));
         } else {
             $r = q("insert into atoken ( atoken_aid, atoken_uid, atoken_name, atoken_token, atoken_expires )\n\t\t\t\t\tvalues ( %d, %d, '%s', '%s', '%s' ) ", intval($channel['channel_account_id']), intval($channel['channel_id']), dbesc($name), dbesc($token), dbesc($expires));
         }
         info(t('Token saved.') . EOL);
         return;
     }
     if (argc() > 1 && argv(1) === 'features') {
         check_form_security_token_redirectOnErr('/settings/features', 'settings_features');
         // Build list of features and check which are set
         $features = get_features();
         $all_features = array();
         foreach ($features as $k => $v) {
             foreach ($v as $f) {
                 $all_features[] = $f[0];
             }
         }
         foreach ($all_features as $k) {
             if (x($_POST, "feature_{$k}")) {
                 set_pconfig(local_channel(), 'feature', $k, 1);
             } else {
                 set_pconfig(local_channel(), 'feature', $k, 0);
             }
         }
         build_sync_packet();
         return;
     }
     if (argc() > 1 && argv(1) == 'display') {
         check_form_security_token_redirectOnErr('/settings/display', 'settings_display');
         $theme = x($_POST, 'theme') ? notags(trim($_POST['theme'])) : \App::$channel['channel_theme'];
         $mobile_theme = x($_POST, 'mobile_theme') ? notags(trim($_POST['mobile_theme'])) : '';
         $preload_images = x($_POST, 'preload_images') ? intval($_POST['preload_images']) : 0;
         $user_scalable = x($_POST, 'user_scalable') ? intval($_POST['user_scalable']) : 0;
         $nosmile = x($_POST, 'nosmile') ? intval($_POST['nosmile']) : 0;
         $title_tosource = x($_POST, 'title_tosource') ? intval($_POST['title_tosource']) : 0;
         $channel_list_mode = x($_POST, 'channel_list_mode') ? intval($_POST['channel_list_mode']) : 0;
         $network_list_mode = x($_POST, 'network_list_mode') ? intval($_POST['network_list_mode']) : 0;
         $channel_divmore_height = x($_POST, 'channel_divmore_height') ? intval($_POST['channel_divmore_height']) : 400;
         if ($channel_divmore_height < 50) {
             $channel_divmore_height = 50;
         }
         $network_divmore_height = x($_POST, 'network_divmore_height') ? intval($_POST['network_divmore_height']) : 400;
         if ($network_divmore_height < 50) {
             $network_divmore_height = 50;
         }
         $browser_update = x($_POST, 'browser_update') ? intval($_POST['browser_update']) : 0;
         $browser_update = $browser_update * 1000;
         if ($browser_update < 10000) {
             $browser_update = 10000;
         }
         $itemspage = x($_POST, 'itemspage') ? intval($_POST['itemspage']) : 20;
         if ($itemspage > 100) {
             $itemspage = 100;
         }
         if ($mobile_theme == "---") {
             del_pconfig(local_channel(), 'system', 'mobile_theme');
         } else {
             set_pconfig(local_channel(), 'system', 'mobile_theme', $mobile_theme);
         }
         set_pconfig(local_channel(), 'system', 'preload_images', $preload_images);
         set_pconfig(local_channel(), 'system', 'user_scalable', $user_scalable);
         set_pconfig(local_channel(), 'system', 'update_interval', $browser_update);
         set_pconfig(local_channel(), 'system', 'itemspage', $itemspage);
         set_pconfig(local_channel(), 'system', 'no_smilies', 1 - intval($nosmile));
         set_pconfig(local_channel(), 'system', 'title_tosource', $title_tosource);
         set_pconfig(local_channel(), 'system', 'channel_list_mode', $channel_list_mode);
         set_pconfig(local_channel(), 'system', 'network_list_mode', $network_list_mode);
         set_pconfig(local_channel(), 'system', 'channel_divmore_height', $channel_divmore_height);
         set_pconfig(local_channel(), 'system', 'network_divmore_height', $network_divmore_height);
         if ($theme == \App::$channel['channel_theme']) {
             // call theme_post only if theme has not been changed
             if (($themeconfigfile = $this->get_theme_config_file($theme)) != null) {
                 require_once $themeconfigfile;
                 theme_post($a);
             }
         }
         $r = q("UPDATE channel SET channel_theme = '%s' WHERE channel_id = %d", dbesc($theme), intval(local_channel()));
         call_hooks('display_settings_post', $_POST);
         build_sync_packet();
         goaway(z_root() . '/settings/display');
         return;
         // NOTREACHED
     }
     if (argc() > 1 && argv(1) === 'account') {
         check_form_security_token_redirectOnErr('/settings/account', 'settings_account');
         call_hooks('account_settings_post', $_POST);
         //		call_hooks('settings_account', $_POST);
         $errs = array();
         $email = x($_POST, 'email') ? trim(notags($_POST['email'])) : '';
         $account = \App::get_account();
         if ($email != $account['account_email']) {
             if (!valid_email($email)) {
                 $errs[] = t('Not valid email.');
             }
             $adm = trim(get_config('system', 'admin_email'));
             if ($adm && strcasecmp($email, $adm) == 0) {
                 $errs[] = t('Protected email address. Cannot change to that email.');
                 $email = \App::$user['email'];
             }
             if (!$errs) {
                 $r = q("update account set account_email = '%s' where account_id = %d", dbesc($email), intval($account['account_id']));
                 if (!$r) {
                     $errs[] = t('System failure storing new email. Please try again.');
                 }
             }
         }
         if ($errs) {
             foreach ($errs as $err) {
                 notice($err . EOL);
             }
             $errs = array();
         }
         if (x($_POST, 'npassword') || x($_POST, 'confirm')) {
             $origpass = trim($_POST['origpass']);
             require_once 'include/auth.php';
             if (!account_verify_password($email, $origpass)) {
                 $errs[] = t('Password verification failed.');
             }
             $newpass = trim($_POST['npassword']);
             $confirm = trim($_POST['confirm']);
             if ($newpass != $confirm) {
                 $errs[] = t('Passwords do not match. Password unchanged.');
             }
             if (!x($newpass) || !x($confirm)) {
                 $errs[] = t('Empty passwords are not allowed. Password unchanged.');
             }
             if (!$errs) {
                 $salt = random_string(32);
                 $password_encoded = hash('whirlpool', $salt . $newpass);
                 $r = q("update account set account_salt = '%s', account_password = '******', account_password_changed = '%s' \n\t\t\t\t\t\twhere account_id = %d", dbesc($salt), dbesc($password_encoded), dbesc(datetime_convert()), intval(get_account_id()));
                 if ($r) {
                     info(t('Password changed.') . EOL);
                 } else {
                     $errs[] = t('Password update failed. Please try again.');
                 }
             }
         }
         if ($errs) {
             foreach ($errs as $err) {
                 notice($err . EOL);
             }
         }
         goaway(z_root() . '/settings/account');
     }
     check_form_security_token_redirectOnErr('/settings', 'settings');
     call_hooks('settings_post', $_POST);
     $set_perms = '';
     $role = x($_POST, 'permissions_role') ? notags(trim($_POST['permissions_role'])) : '';
     $oldrole = get_pconfig(local_channel(), 'system', 'permissions_role');
     if ($role != $oldrole || $role === 'custom') {
         if ($role === 'custom') {
             $hide_presence = x($_POST, 'hide_presence') && intval($_POST['hide_presence']) == 1 ? 1 : 0;
             $publish = x($_POST, 'profile_in_directory') && intval($_POST['profile_in_directory']) == 1 ? 1 : 0;
             $def_group = x($_POST, 'group-selection') ? notags(trim($_POST['group-selection'])) : '';
             $r = q("update channel set channel_default_group = '%s' where channel_id = %d", dbesc($def_group), intval(local_channel()));
             $global_perms = get_perms();
             foreach ($global_perms as $k => $v) {
                 $set_perms .= ', ' . $v[0] . ' = ' . intval($_POST[$k]) . ' ';
             }
             $acl = new \Zotlabs\Access\AccessList($channel);
             $acl->set_from_array($_POST);
             $x = $acl->get();
             $r = q("update channel set channel_allow_cid = '%s', channel_allow_gid = '%s', \n\t\t\t\t\tchannel_deny_cid = '%s', channel_deny_gid = '%s' where channel_id = %d", dbesc($x['allow_cid']), dbesc($x['allow_gid']), dbesc($x['deny_cid']), dbesc($x['deny_gid']), intval(local_channel()));
         } else {
             $role_permissions = get_role_perms($_POST['permissions_role']);
             if (!$role_permissions) {
                 notice('Permissions category could not be found.');
                 return;
             }
             $hide_presence = 1 - intval($role_permissions['online']);
             if ($role_permissions['default_collection']) {
                 $r = q("select hash from groups where uid = %d and gname = '%s' limit 1", intval(local_channel()), dbesc(t('Friends')));
                 if (!$r) {
                     require_once 'include/group.php';
                     group_add(local_channel(), t('Friends'));
                     group_add_member(local_channel(), t('Friends'), $channel['channel_hash']);
                     $r = q("select hash from groups where uid = %d and gname = '%s' limit 1", intval(local_channel()), dbesc(t('Friends')));
                 }
                 if ($r) {
                     q("update channel set channel_default_group = '%s', channel_allow_gid = '%s', channel_allow_cid = '', channel_deny_gid = '', channel_deny_cid = '' where channel_id = %d", dbesc($r[0]['hash']), dbesc('<' . $r[0]['hash'] . '>'), intval(local_channel()));
                 } else {
                     notice(sprintf('Default privacy group \'%s\' not found. Please create and re-submit permission change.', t('Friends')) . EOL);
                     return;
                 }
             } else {
                 q("update channel set channel_default_group = '', channel_allow_gid = '', channel_allow_cid = '', channel_deny_gid = '', \n\t\t\t\t\t\tchannel_deny_cid = '' where channel_id = %d", intval(local_channel()));
             }
             $r = q("update abook set abook_my_perms  = %d where abook_channel = %d and abook_self = 1", intval(array_key_exists('perms_accept', $role_permissions) ? $role_permissions['perms_accept'] : 0), intval(local_channel()));
             set_pconfig(local_channel(), 'system', 'autoperms', $role_permissions['perms_auto'] ? intval($role_permissions['perms_accept']) : 0);
             foreach ($role_permissions as $p => $v) {
                 if (strpos($p, 'channel_') !== false) {
                     $set_perms .= ', ' . $p . ' = ' . intval($v) . ' ';
                 }
                 if ($p === 'directory_publish') {
                     $publish = intval($v);
                 }
             }
         }
         set_pconfig(local_channel(), 'system', 'hide_online_status', $hide_presence);
         set_pconfig(local_channel(), 'system', 'permissions_role', $role);
     }
     $username = x($_POST, 'username') ? notags(trim($_POST['username'])) : '';
     $timezone = x($_POST, 'timezone_select') ? notags(trim($_POST['timezone_select'])) : '';
     $defloc = x($_POST, 'defloc') ? notags(trim($_POST['defloc'])) : '';
     $openid = x($_POST, 'openid_url') ? notags(trim($_POST['openid_url'])) : '';
     $maxreq = x($_POST, 'maxreq') ? intval($_POST['maxreq']) : 0;
     $expire = x($_POST, 'expire') ? intval($_POST['expire']) : 0;
     $evdays = x($_POST, 'evdays') ? intval($_POST['evdays']) : 3;
     $photo_path = x($_POST, 'photo_path') ? escape_tags(trim($_POST['photo_path'])) : '';
     $attach_path = x($_POST, 'attach_path') ? escape_tags(trim($_POST['attach_path'])) : '';
     $channel_menu = x($_POST['channel_menu']) ? htmlspecialchars_decode(trim($_POST['channel_menu']), ENT_QUOTES) : '';
     $expire_items = x($_POST, 'expire_items') ? intval($_POST['expire_items']) : 0;
     $expire_starred = x($_POST, 'expire_starred') ? intval($_POST['expire_starred']) : 0;
     $expire_photos = x($_POST, 'expire_photos') ? intval($_POST['expire_photos']) : 0;
     $expire_network_only = x($_POST, 'expire_network_only') ? intval($_POST['expire_network_only']) : 0;
     $allow_location = x($_POST, 'allow_location') && intval($_POST['allow_location']) == 1 ? 1 : 0;
     $blocktags = x($_POST, 'blocktags') && intval($_POST['blocktags']) == 1 ? 0 : 1;
     // this setting is inverted!
     $unkmail = x($_POST, 'unkmail') && intval($_POST['unkmail']) == 1 ? 1 : 0;
     $cntunkmail = x($_POST, 'cntunkmail') ? intval($_POST['cntunkmail']) : 0;
     $suggestme = x($_POST, 'suggestme') ? intval($_POST['suggestme']) : 0;
     $post_newfriend = $_POST['post_newfriend'] == 1 ? 1 : 0;
     $post_joingroup = $_POST['post_joingroup'] == 1 ? 1 : 0;
     $post_profilechange = $_POST['post_profilechange'] == 1 ? 1 : 0;
     $adult = $_POST['adult'] == 1 ? 1 : 0;
     $cal_first_day = x($_POST, 'first_day') && intval($_POST['first_day']) == 1 ? 1 : 0;
     $channel = \App::get_channel();
     $pageflags = $channel['channel_pageflags'];
     $existing_adult = $pageflags & PAGE_ADULT ? 1 : 0;
     if ($adult != $existing_adult) {
         $pageflags = $pageflags ^ PAGE_ADULT;
     }
     $notify = 0;
     if (x($_POST, 'notify1')) {
         $notify += intval($_POST['notify1']);
     }
     if (x($_POST, 'notify2')) {
         $notify += intval($_POST['notify2']);
     }
     if (x($_POST, 'notify3')) {
         $notify += intval($_POST['notify3']);
     }
     if (x($_POST, 'notify4')) {
         $notify += intval($_POST['notify4']);
     }
     if (x($_POST, 'notify5')) {
         $notify += intval($_POST['notify5']);
     }
     if (x($_POST, 'notify6')) {
         $notify += intval($_POST['notify6']);
     }
     if (x($_POST, 'notify7')) {
         $notify += intval($_POST['notify7']);
     }
     if (x($_POST, 'notify8')) {
         $notify += intval($_POST['notify8']);
     }
     $vnotify = 0;
     if (x($_POST, 'vnotify1')) {
         $vnotify += intval($_POST['vnotify1']);
     }
     if (x($_POST, 'vnotify2')) {
         $vnotify += intval($_POST['vnotify2']);
     }
     if (x($_POST, 'vnotify3')) {
         $vnotify += intval($_POST['vnotify3']);
     }
     if (x($_POST, 'vnotify4')) {
         $vnotify += intval($_POST['vnotify4']);
     }
     if (x($_POST, 'vnotify5')) {
         $vnotify += intval($_POST['vnotify5']);
     }
     if (x($_POST, 'vnotify6')) {
         $vnotify += intval($_POST['vnotify6']);
     }
     if (x($_POST, 'vnotify7')) {
         $vnotify += intval($_POST['vnotify7']);
     }
     if (x($_POST, 'vnotify8')) {
         $vnotify += intval($_POST['vnotify8']);
     }
     if (x($_POST, 'vnotify9')) {
         $vnotify += intval($_POST['vnotify9']);
     }
     if (x($_POST, 'vnotify10')) {
         $vnotify += intval($_POST['vnotify10']);
     }
     if (x($_POST, 'vnotify11')) {
         $vnotify += intval($_POST['vnotify11']);
     }
     $always_show_in_notices = x($_POST, 'always_show_in_notices') ? 1 : 0;
     $channel = \App::get_channel();
     $err = '';
     $name_change = false;
     if ($username != $channel['channel_name']) {
         $name_change = true;
         require_once 'include/channel.php';
         $err = validate_channelname($username);
         if ($err) {
             notice($err);
             return;
         }
     }
     if ($timezone != $channel['channel_timezone']) {
         if (strlen($timezone)) {
             date_default_timezone_set($timezone);
         }
     }
     set_pconfig(local_channel(), 'system', 'use_browser_location', $allow_location);
     set_pconfig(local_channel(), 'system', 'suggestme', $suggestme);
     set_pconfig(local_channel(), 'system', 'post_newfriend', $post_newfriend);
     set_pconfig(local_channel(), 'system', 'post_joingroup', $post_joingroup);
     set_pconfig(local_channel(), 'system', 'post_profilechange', $post_profilechange);
     set_pconfig(local_channel(), 'system', 'blocktags', $blocktags);
     set_pconfig(local_channel(), 'system', 'channel_menu', $channel_menu);
     set_pconfig(local_channel(), 'system', 'vnotify', $vnotify);
     set_pconfig(local_channel(), 'system', 'always_show_in_notices', $always_show_in_notices);
     set_pconfig(local_channel(), 'system', 'evdays', $evdays);
     set_pconfig(local_channel(), 'system', 'photo_path', $photo_path);
     set_pconfig(local_channel(), 'system', 'attach_path', $attach_path);
     set_pconfig(local_channel(), 'system', 'cal_first_day', $cal_first_day);
     $r = q("update channel set channel_name = '%s', channel_pageflags = %d, channel_timezone = '%s', channel_location = '%s', channel_notifyflags = %d, channel_max_anon_mail = %d, channel_max_friend_req = %d, channel_expire_days = %d {$set_perms} where channel_id = %d", dbesc($username), intval($pageflags), dbesc($timezone), dbesc($defloc), intval($notify), intval($unkmail), intval($maxreq), intval($expire), intval(local_channel()));
     if ($r) {
         info(t('Settings updated.') . EOL);
     }
     if (!is_null($publish)) {
         $r = q("UPDATE profile SET publish = %d WHERE is_default = 1 AND uid = %d", intval($publish), intval(local_channel()));
     }
     if ($name_change) {
         $r = q("update xchan set xchan_name = '%s', xchan_name_date = '%s' where xchan_hash = '%s'", dbesc($username), dbesc(datetime_convert()), dbesc($channel['channel_hash']));
         $r = q("update profile set fullname = '%s' where uid = %d and is_default = 1", dbesc($username), intval($channel['channel_id']));
     }
     \Zotlabs\Daemon\Master::Summon(array('Directory', local_channel()));
     build_sync_packet();
     //$_SESSION['theme'] = $theme;
     if ($email_changed && \App::$config['system']['register_policy'] == REGISTER_VERIFY) {
         // FIXME - set to un-verified, blocked and redirect to logout
         // Why? Are we verifying people or email addresses?
     }
     goaway(z_root() . '/settings');
     return;
     // NOTREACHED
 }
Beispiel #6
0
 function post()
 {
     logger('post: ' . print_r($_REQUEST, true), LOGGER_DATA);
     if (!local_channel()) {
         return;
     }
     if ($_FILES && array_key_exists('userfile', $_FILES) && intval($_FILES['userfile']['size'])) {
         $src = $_FILES['userfile']['tmp_name'];
         if ($src) {
             $result = parse_ical_file($src, local_channel());
             if ($result) {
                 info(t('Calendar entries imported.') . EOL);
             } else {
                 notice(t('No calendar entries found.') . EOL);
             }
             @unlink($src);
         }
         goaway(z_root() . '/events');
     }
     $event_id = x($_POST, 'event_id') ? intval($_POST['event_id']) : 0;
     $event_hash = x($_POST, 'event_hash') ? $_POST['event_hash'] : '';
     $xchan = x($_POST, 'xchan') ? dbesc($_POST['xchan']) : '';
     $uid = local_channel();
     $start_text = escape_tags($_REQUEST['start_text']);
     $finish_text = escape_tags($_REQUEST['finish_text']);
     $adjust = intval($_POST['adjust']);
     $nofinish = intval($_POST['nofinish']);
     $categories = escape_tags(trim($_POST['category']));
     // only allow editing your own events.
     if ($xchan && $xchan !== get_observer_hash()) {
         return;
     }
     if ($start_text) {
         $start = $start_text;
     } else {
         $start = sprintf('%d-%d-%d %d:%d:0', $startyear, $startmonth, $startday, $starthour, $startminute);
     }
     if ($nofinish) {
         $finish = NULL_DATE;
     }
     if ($finish_text) {
         $finish = $finish_text;
     } else {
         $finish = sprintf('%d-%d-%d %d:%d:0', $finishyear, $finishmonth, $finishday, $finishhour, $finishminute);
     }
     if ($adjust) {
         $start = datetime_convert(date_default_timezone_get(), 'UTC', $start);
         if (!$nofinish) {
             $finish = datetime_convert(date_default_timezone_get(), 'UTC', $finish);
         }
     } else {
         $start = datetime_convert('UTC', 'UTC', $start);
         if (!$nofinish) {
             $finish = datetime_convert('UTC', 'UTC', $finish);
         }
     }
     // Don't allow the event to finish before it begins.
     // It won't hurt anything, but somebody will file a bug report
     // and we'll waste a bunch of time responding to it. Time that
     // could've been spent doing something else.
     $summary = escape_tags(trim($_POST['summary']));
     $desc = escape_tags(trim($_POST['desc']));
     $location = escape_tags(trim($_POST['location']));
     $type = escape_tags(trim($_POST['type']));
     require_once 'include/text.php';
     linkify_tags($a, $desc, local_channel());
     linkify_tags($a, $location, local_channel());
     //$action = ($event_hash == '') ? 'new' : "event/" . $event_hash;
     //fixme: this url gives a wsod if there is a linebreak detected in one of the variables ($desc or $location)
     //$onerror_url = z_root() . "/events/" . $action . "?summary=$summary&description=$desc&location=$location&start=$start_text&finish=$finish_text&adjust=$adjust&nofinish=$nofinish&type=$type";
     $onerror_url = z_root() . "/events";
     if (strcmp($finish, $start) < 0 && !$nofinish) {
         notice(t('Event can not end before it has started.') . EOL);
         if (intval($_REQUEST['preview'])) {
             echo t('Unable to generate preview.');
             killme();
         }
         goaway($onerror_url);
     }
     if (!$summary || !$start) {
         notice(t('Event title and start time are required.') . EOL);
         if (intval($_REQUEST['preview'])) {
             echo t('Unable to generate preview.');
             killme();
         }
         goaway($onerror_url);
     }
     $share = intval($_POST['share']) ? intval($_POST['share']) : 0;
     $channel = \App::get_channel();
     $acl = new \Zotlabs\Access\AccessList(false);
     if ($event_id) {
         $x = q("select * from event where id = %d and uid = %d limit 1", intval($event_id), intval(local_channel()));
         if (!$x) {
             notice(t('Event not found.') . EOL);
             if (intval($_REQUEST['preview'])) {
                 echo t('Unable to generate preview.');
                 killme();
             }
             return;
         }
         $acl->set($x[0]);
         $created = $x[0]['created'];
         $edited = datetime_convert();
         if ($x[0]['allow_cid'] === '<' . $channel['channel_hash'] . '>' && $x[0]['allow_gid'] === '' && $x[0]['deny_cid'] === '' && $x[0]['deny_gid'] === '') {
             $share = false;
         } else {
             $share = true;
         }
     } else {
         $created = $edited = datetime_convert();
         if ($share) {
             $acl->set_from_array($_POST);
         } else {
             $acl->set(array('allow_cid' => '<' . $channel['channel_hash'] . '>', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => ''));
         }
     }
     $post_tags = array();
     $channel = \App::get_channel();
     $ac = $acl->get();
     if (strlen($categories)) {
         $cats = explode(',', $categories);
         foreach ($cats as $cat) {
             $post_tags[] = array('uid' => $profile_uid, 'ttype' => TERM_CATEGORY, 'otype' => TERM_OBJ_POST, 'term' => trim($cat), 'url' => $channel['xchan_url'] . '?f=&cat=' . urlencode(trim($cat)));
         }
     }
     $datarray = array();
     $datarray['dtstart'] = $start;
     $datarray['dtend'] = $finish;
     $datarray['summary'] = $summary;
     $datarray['description'] = $desc;
     $datarray['location'] = $location;
     $datarray['etype'] = $type;
     $datarray['adjust'] = $adjust;
     $datarray['nofinish'] = $nofinish;
     $datarray['uid'] = local_channel();
     $datarray['account'] = get_account_id();
     $datarray['event_xchan'] = $channel['channel_hash'];
     $datarray['allow_cid'] = $ac['allow_cid'];
     $datarray['allow_gid'] = $ac['allow_gid'];
     $datarray['deny_cid'] = $ac['deny_cid'];
     $datarray['deny_gid'] = $ac['deny_gid'];
     $datarray['private'] = $acl->is_private() ? 1 : 0;
     $datarray['id'] = $event_id;
     $datarray['created'] = $created;
     $datarray['edited'] = $edited;
     if (intval($_REQUEST['preview'])) {
         $html = format_event_html($datarray);
         echo $html;
         killme();
     }
     $event = event_store_event($datarray);
     if ($post_tags) {
         $datarray['term'] = $post_tags;
     }
     $item_id = event_store_item($datarray, $event);
     if ($item_id) {
         $r = q("select * from item where id = %d", intval($item_id));
         if ($r) {
             xchan_query($r);
             $sync_item = fetch_post_tags($r);
             $z = q("select * from event where event_hash = '%s' and uid = %d limit 1", dbesc($r[0]['resource_id']), intval($channel['channel_id']));
             if ($z) {
                 build_sync_packet($channel['channel_id'], array('event_item' => array(encode_item($sync_item[0], true)), 'event' => $z));
             }
         }
     }
     if ($share) {
         \Zotlabs\Daemon\Master::Summon(array('Notifier', 'event', $item_id));
     }
 }
Beispiel #7
0
/**
 * @brief This function provides the API endpoints, primarily called by the 
 * JavaScript functions via $.post() calls.
 *
 * @return json JSON-formatted structures with a "status" indicator for success
 * as well as other requested data
 */
function chess_post(&$a)
{
    if (argc() > 1) {
        switch (argv(1)) {
            // API: /chess/settings
            // Updates game settings for the observer
            case 'settings':
                $observer = App::get_observer();
                $settings = x($_POST, 'settings') ? $_POST['settings'] : null;
                $settings = json_decode($settings, true);
                if (!isset($settings['notify_enabled'])) {
                    json_return_and_die(array('errormsg' => 'Invalid settings', 'status' => false));
                }
                $notify_enable = intval($settings['notify_enabled']);
                set_xconfig($observer['xchan_hash'], 'chess', 'notifications', $notify_enable);
                json_return_and_die(array('status' => true));
                // API: /chess/resume
                // Resumes a game specified by "game_id" allowing further moves
            // API: /chess/resume
            // Resumes a game specified by "game_id" allowing further moves
            case 'resume':
                $observer = App::get_observer();
                $game_id = x($_POST, 'game_id') ? $_POST['game_id'] : '';
                $g = chess_get_game($game_id);
                if (!$g['status']) {
                    json_return_and_die(array('errormsg' => 'Invalid game', 'status' => false));
                }
                // Verify that observer is a valid player
                $game = json_decode($g['game']['obj'], true);
                if (!in_array($observer['xchan_hash'], $game['players'])) {
                    json_return_and_die(array('errormsg' => 'You are not a valid player', 'status' => false));
                }
                $success = chess_resume_game($g['game']);
                if (!$success) {
                    json_return_and_die(array('errormsg' => 'Error resuming game', 'status' => false));
                } else {
                    json_return_and_die(array('status' => true));
                }
                // API: /chess/end
                // Ends a game specified by "game_id" preventing further moves
            // API: /chess/end
            // Ends a game specified by "game_id" preventing further moves
            case 'end':
                $observer = App::get_observer();
                $game_id = x($_POST, 'game_id') ? $_POST['game_id'] : '';
                $g = chess_get_game($game_id);
                if (!$g['status']) {
                    json_return_and_die(array('errormsg' => 'Invalid game', 'status' => false));
                }
                // Verify that observer is a valid player
                $game = json_decode($g['game']['obj'], true);
                if (!in_array($observer['xchan_hash'], $game['players'])) {
                    json_return_and_die(array('errormsg' => 'You are not a valid player', 'status' => false));
                }
                $success = chess_end_game($g['game']);
                if (!$success) {
                    json_return_and_die(array('errormsg' => 'Error ending game', 'status' => false));
                } else {
                    json_return_and_die(array('status' => true));
                }
                // API: /chess/delete
                // Deletes a game specified by "game_id"
            // API: /chess/delete
            // Deletes a game specified by "game_id"
            case 'delete':
                if (!local_channel()) {
                    json_return_and_die(array('errormsg' => 'Must be local channel.', 'status' => false));
                }
                $channel = App::get_channel();
                $game_id = x($_POST, 'game_id') ? $_POST['game_id'] : '';
                $d = chess_delete_game($game_id, $channel);
                if (!$d['status']) {
                    json_return_and_die(array('errormsg' => 'Error deleting game', 'status' => false));
                } else {
                    json_return_and_die(array('status' => true));
                }
                // API: /chess/revert
                // Reverts a game specified by "game_id" to a previous board position
                // specified by the "mid" of the child post of the original game post
                // in the item table
                // TODO: Determine why the board position in the game item is not actually
                // being reverted
            // API: /chess/revert
            // Reverts a game specified by "game_id" to a previous board position
            // specified by the "mid" of the child post of the original game post
            // in the item table
            // TODO: Determine why the board position in the game item is not actually
            // being reverted
            case 'revert':
                $observer = App::get_observer();
                $game_id = $_POST['game_id'];
                $g = chess_get_game($game_id);
                if (!$g['status']) {
                    json_return_and_die(array('errormsg' => 'Invalid game', 'status' => false));
                }
                // Verify that observer is a valid player
                $game = json_decode($g['game']['obj'], true);
                if (!in_array($observer['xchan_hash'], $game['players'])) {
                    json_return_and_die(array('errormsg' => 'You are not a valid player', 'status' => false));
                }
                $active = $game['active'] === $observer['xchan_hash'] ? true : false;
                if (!$active) {
                    json_return_and_die(array('errormsg' => 'It is not your turn', 'status' => false));
                }
                $r = chess_revert_position($g['game'], $observer, $_POST['mid']);
                if (!$r['status']) {
                    json_return_and_die(array('errormsg' => 'Error reverting game', 'status' => false));
                }
                json_return_and_die(array('status' => true));
                // API: /chess/history
                // Retrieves all the board positions for a game in order to populate the
                // history viewer in the control panel
            // API: /chess/history
            // Retrieves all the board positions for a game in order to populate the
            // history viewer in the control panel
            case 'history':
                $observer = App::get_observer();
                $game_id = $_POST['game_id'];
                $g = chess_get_game($game_id);
                if (!$g['status']) {
                    json_return_and_die(array('errormsg' => 'Invalid game', 'status' => false));
                }
                // Verify that observer is a valid player
                $game = json_decode($g['game']['obj'], true);
                if (!in_array($observer['xchan_hash'], $game['players'])) {
                    json_return_and_die(array('errormsg' => 'You are not a valid player', 'status' => false));
                }
                $player = array_search($observer['xchan_hash'], $game['players']);
                $h = chess_get_history($g['game']);
                if (!$h['status']) {
                    json_return_and_die(array('errormsg' => 'Error retrieving game history', 'status' => false));
                }
                json_return_and_die(array('history' => $h['history'], 'status' => true));
                // API: /chess/update
                // Updates a game specified by "game_id" with a new board position specified
                // by "newPosFEN" in FEN-format
            // API: /chess/update
            // Updates a game specified by "game_id" with a new board position specified
            // by "newPosFEN" in FEN-format
            case 'update':
                $observer = App::get_observer();
                $game_id = $_POST['game_id'];
                $g = chess_get_game($game_id);
                if (!$g['status']) {
                    json_return_and_die(array('errormsg' => 'Invalid game', 'status' => false));
                }
                // Verify that observer is a valid player
                $game = json_decode($g['game']['obj'], true);
                if (!in_array($observer['xchan_hash'], $game['players'])) {
                    json_return_and_die(array('errormsg' => 'You are not a valid player', 'status' => false));
                }
                $player = array_search($observer['xchan_hash'], $game['players']);
                $active = $game['active'] === $game['players'][$player] ? true : false;
                json_return_and_die(array('position' => $game['position'], 'myturn' => $active, 'ended' => $game['ended'], 'status' => true));
                // API: /chess/move
                // Adds a new board position by creating a child post for the original
                // game item.
            // API: /chess/move
            // Adds a new board position by creating a child post for the original
            // game item.
            case 'move':
                $observer = App::get_observer();
                $game_id = $_POST['game_id'];
                $newPosFEN = $_POST['newPosFEN'];
                $g = chess_get_game($game_id);
                if (!$g['status']) {
                    notice(t('Invalid game.') . EOL);
                    json_return_and_die(array('errormsg' => 'Invalid game ID', 'status' => false));
                }
                // Verify that observer is a valid player
                $game = json_decode($g['game']['obj'], true);
                if (!in_array($observer['xchan_hash'], $game['players'])) {
                    notice(t('You are not a player in this game.') . EOL);
                    goaway('/chess');
                }
                $player = array_search($observer['xchan_hash'], $game['players']);
                $color = $game['colors'][$player];
                $active = $game['active'] === $observer['xchan_hash'] ? true : false;
                if (!$active) {
                    json_return_and_die(array('errormsg' => 'It is not your turn', 'status' => false));
                }
                if (x($game, 'ended') && intval($game['ended']) === 1) {
                    json_return_and_die(array('errormsg' => 'The game is over', 'status' => false));
                }
                $move = chess_make_move($observer, $newPosFEN, $g['game']);
                if ($move['status']) {
                    $active_xchan = $game['players'][0] === $observer['xchan_hash'] ? $game['players'][1] : $game['players'][0];
                    if (chess_set_position(chess_get_game($game_id)['game'], $newPosFEN)) {
                        chess_set_active(chess_get_game($game_id)['game'], $active_xchan);
                    }
                    json_return_and_die(array('status' => true));
                } else {
                    json_return_and_die(array('errormsg' => 'Move failed', 'status' => false));
                }
            default:
                break;
        }
    }
    if (argc() > 2) {
        switch (argv(2)) {
            // API: /chess/[channelname]/new/
            // This endpoint handles the new game form submission and creates a new
            // game between two channels specified by the standard ACL
            case 'new':
                if (!local_channel()) {
                    notice(t('You must be a local channel to create a game.') . EOL);
                    return;
                }
                // Ensure ACL specifies exactly one other channel
                $channel = App::get_channel();
                $acl = new Zotlabs\Access\AccessList($channel);
                $acl->set_from_array($_REQUEST);
                $perms = $acl->get();
                $allow_cid = expand_acl($perms['allow_cid']);
                $valid = 0;
                if (count($allow_cid) > 1) {
                    foreach ($allow_cid as $allow) {
                        if ($allow == $channel['channel_hash']) {
                            continue;
                        }
                        $valid++;
                    }
                }
                if ($valid != 1) {
                    notice(t('You must select one opponent that is not yourself.') . EOL);
                    return;
                } else {
                    info(t('Creating new game...') . EOL);
                    // Get the game owner's color choice
                    $color = '';
                    if ($_POST['color'] === 'white' || $_POST['color'] === 'black') {
                        $color = $_POST['color'];
                    } else {
                        notice(t('You must select white or black.') . EOL);
                        return;
                    }
                    $game = chess_create_game($channel, $color, $acl);
                    if ($game['status']) {
                        goaway('/chess/' . $channel['channel_address'] . '/' . $game['item']['resource_id']);
                    } else {
                        notice(t('Error creating new game.') . EOL);
                    }
                    return;
                }
            default:
                break;
        }
    }
}
Beispiel #8
0
function menu_edit_item($menu_id, $uid, $arr)
{
    $mitem_id = intval($arr['mitem_id']);
    $mitem_link = escape_tags($arr['mitem_link']);
    $mitem_desc = escape_tags($arr['mitem_desc']);
    $mitem_order = intval($arr['mitem_order']);
    $mitem_flags = intval($arr['mitem_flags']);
    if (local_channel() == $uid) {
        $channel = App::get_channel();
    }
    $acl = new Zotlabs\Access\AccessList($channel);
    $acl->set_from_array($arr);
    $p = $acl->get();
    $r = q("update menu_item set mitem_link = '%s', mitem_desc = '%s', mitem_flags = %d, allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', mitem_order = %d  where mitem_channel_id = %d and mitem_menu_id = %d and mitem_id = %d", dbesc($mitem_link), dbesc($mitem_desc), intval($mitem_flags), dbesc($p['allow_cid']), dbesc($p['allow_gid']), dbesc($p['deny_cid']), dbesc($p['deny_gid']), intval($mitem_order), intval($uid), intval($menu_id), intval($mitem_id));
    $x = q("update menu set menu_edited = '%s' where menu_id = %d and menu_channel_id = %d", dbesc(datetime_convert()), intval($menu_id), intval($uid));
    return $r;
}
Beispiel #9
0
 function post()
 {
     logger('mod-photos: photos_post: begin', LOGGER_DEBUG);
     logger('mod_photos: REQUEST ' . print_r($_REQUEST, true), LOGGER_DATA);
     logger('mod_photos: FILES ' . print_r($_FILES, true), LOGGER_DATA);
     $ph = photo_factory('');
     $phototypes = $ph->supportedTypes();
     $can_post = false;
     $page_owner_uid = \App::$data['channel']['channel_id'];
     if (perm_is_allowed($page_owner_uid, get_observer_hash(), 'write_storage')) {
         $can_post = true;
     }
     if (!$can_post) {
         notice(t('Permission denied.') . EOL);
         if (is_ajax()) {
             killme();
         }
         return;
     }
     $s = abook_self($page_owner_uid);
     if (!$s) {
         notice(t('Page owner information could not be retrieved.') . EOL);
         logger('mod_photos: post: unable to locate contact record for page owner. uid=' . $page_owner_uid);
         if (is_ajax()) {
             killme();
         }
         return;
     }
     $owner_record = $s[0];
     $acl = new \Zotlabs\Access\AccessList(\App::$data['channel']);
     if (argc() > 3 && argv(2) === 'album') {
         $album = hex2bin(argv(3));
         if ($album === t('Profile Photos')) {
             // not allowed
             goaway(z_root() . '/' . $_SESSION['photo_return']);
         }
         if (!photos_album_exists($page_owner_uid, $album)) {
             notice(t('Album not found.') . EOL);
             goaway(z_root() . '/' . $_SESSION['photo_return']);
         }
         /*
          * DELETE photo album and all its photos
          */
         if ($_REQUEST['dropalbum'] == t('Delete Album')) {
             // This is dangerous because we combined file storage and photos into one interface
             // This function will remove all photos from any directory with the same name since
             // we have not passed the path value.
             // The correct solution would be to use a full pathname from your storage root for 'album'
             // We also need to prevent/block removing the storage root folder.
             $folder_hash = '';
             $r = q("select * from attach where is_dir = 1 and uid = %d and filename = '%s'", intval($page_owner_uid), dbesc($album));
             if (!$r) {
                 notice(t('Album not found.') . EOL);
                 return;
             }
             if (count($r) > 1) {
                 notice(t('Multiple storage folders exist with this album name, but within different directories. Please remove the desired folder or folders using the Files manager') . EOL);
                 return;
             } else {
                 $folder_hash = $r[0]['hash'];
             }
             $res = array();
             // get the list of photos we are about to delete
             if (remote_channel() && !local_channel()) {
                 $str = photos_album_get_db_idstr($page_owner_uid, $album, remote_channel());
             } elseif (local_channel()) {
                 $str = photos_album_get_db_idstr(local_channel(), $album);
             } else {
                 $str = null;
             }
             if (!$str) {
                 goaway(z_root() . '/' . $_SESSION['photo_return']);
             }
             $r = q("select id from item where resource_id in ( {$str} ) and resource_type = 'photo' and uid = %d " . item_normal(), intval($page_owner_uid));
             if ($r) {
                 foreach ($r as $i) {
                     attach_delete($page_owner_uid, $i['resource_id'], 1);
                 }
             }
             // remove the associated photos in case they weren't attached to an item
             q("delete from photo where resource_id in ( {$str} ) and uid = %d", intval($page_owner_uid));
             // @FIXME do the same for the linked attach
             if ($folder_hash) {
                 attach_delete($page_owner_uid, $folder_hash, 1);
                 $sync = attach_export_data(\App::$data['channel'], $folder_hash, true);
                 if ($sync) {
                     build_sync_packet($page_owner_uid, array('file' => array($sync)));
                 }
             }
         }
         goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address']);
     }
     if (argc() > 2 && x($_REQUEST, 'delete') && $_REQUEST['delete'] === t('Delete Photo')) {
         // same as above but remove single photo
         $ob_hash = get_observer_hash();
         if (!$ob_hash) {
             goaway(z_root() . '/' . $_SESSION['photo_return']);
         }
         $r = q("SELECT `id`, `resource_id` FROM `photo` WHERE ( xchan = '%s' or `uid` = %d ) AND `resource_id` = '%s' LIMIT 1", dbesc($ob_hash), intval(local_channel()), dbesc(\App::$argv[2]));
         if ($r) {
             attach_delete($page_owner_uid, $r[0]['resource_id'], 1);
             $sync = attach_export_data(\App::$data['channel'], $r[0]['resource_id'], true);
             if ($sync) {
                 build_sync_packet($page_owner_uid, array('file' => array($sync)));
             }
         }
         goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . $_SESSION['album_return']);
     }
     if (argc() > 2 && array_key_exists('move_to_album', $_POST)) {
         $m = q("select folder from attach where hash = '%s' and uid = %d limit 1", dbesc(argv(2)), intval($page_owner_uid));
         if ($m && $m[0]['folder'] != $_POST['move_to_album']) {
             attach_move($page_owner_uid, argv(2), $_POST['move_to_album']);
             if (!($_POST['desc'] && $_POST['newtag'])) {
                 goaway(z_root() . '/' . $_SESSION['photo_return']);
             }
         }
     }
     if (argc() > 2 && (x($_POST, 'desc') !== false || x($_POST, 'newtag') !== false)) {
         $desc = x($_POST, 'desc') ? notags(trim($_POST['desc'])) : '';
         $rawtags = x($_POST, 'newtag') ? notags(trim($_POST['newtag'])) : '';
         $item_id = x($_POST, 'item_id') ? intval($_POST['item_id']) : 0;
         $is_nsfw = x($_POST, 'adult') ? intval($_POST['adult']) : 0;
         $acl->set_from_array($_POST);
         $perm = $acl->get();
         $resource_id = argv(2);
         if (x($_POST, 'rotate') !== false && (intval($_POST['rotate']) == 1 || intval($_POST['rotate']) == 2)) {
             logger('rotate');
             $r = q("select * from photo where `resource_id` = '%s' and uid = %d and imgscale = 0 limit 1", dbesc($resource_id), intval($page_owner_uid));
             if (count($r)) {
                 $d = $r[0]['os_storage'] ? @file_get_contents($r[0]['content']) : dbunescbin($r[0]['content']);
                 $ph = photo_factory($d, $r[0]['mimetype']);
                 if ($ph->is_valid()) {
                     $rotate_deg = intval($_POST['rotate']) == 1 ? 270 : 90;
                     $ph->rotate($rotate_deg);
                     $width = $ph->getWidth();
                     $height = $ph->getHeight();
                     if (intval($r[0]['os_storage'])) {
                         @file_put_contents($r[0]['content'], $ph->imageString());
                         $data = $r[0]['content'];
                         $fsize = @filesize($r[0]['content']);
                         q("update attach set filesize = %d where hash = '%s' and uid = %d limit 1", intval($fsize), dbesc($resource_id), intval($page_owner_uid));
                     } else {
                         $data = $ph->imageString();
                         $fsize = strlen($data);
                     }
                     $x = q("update photo set content = '%s', filesize = %d, height = %d, width = %d where `resource_id` = '%s' and uid = %d and imgscale = 0", dbescbin($data), intval($fsize), intval($height), intval($width), dbesc($resource_id), intval($page_owner_uid));
                     if ($width > 1024 || $height > 1024) {
                         $ph->scaleImage(1024);
                     }
                     $width = $ph->getWidth();
                     $height = $ph->getHeight();
                     $x = q("update photo set content = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and imgscale = 1", dbescbin($ph->imageString()), intval($height), intval($width), dbesc($resource_id), intval($page_owner_uid));
                     if ($width > 640 || $height > 640) {
                         $ph->scaleImage(640);
                     }
                     $width = $ph->getWidth();
                     $height = $ph->getHeight();
                     $x = q("update photo set content = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and imgscale = 2", dbescbin($ph->imageString()), intval($height), intval($width), dbesc($resource_id), intval($page_owner_uid));
                     if ($width > 320 || $height > 320) {
                         $ph->scaleImage(320);
                     }
                     $width = $ph->getWidth();
                     $height = $ph->getHeight();
                     $x = q("update photo set content = '%s', height = %d, width = %d where `resource_id` = '%s' and uid = %d and imgscale = 3", dbescbin($ph->imageString()), intval($height), intval($width), dbesc($resource_id), intval($page_owner_uid));
                 }
             }
         }
         $p = q("SELECT mimetype, is_nsfw, description, resource_id, imgscale, allow_cid, allow_gid, deny_cid, deny_gid FROM photo WHERE resource_id = '%s' AND uid = %d ORDER BY imgscale DESC", dbesc($resource_id), intval($page_owner_uid));
         if ($p) {
             $ext = $phototypes[$p[0]['mimetype']];
             $r = q("UPDATE `photo` SET `description` = '%s', `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s' WHERE `resource_id` = '%s' AND `uid` = %d", dbesc($desc), dbesc($perm['allow_cid']), dbesc($perm['allow_gid']), dbesc($perm['deny_cid']), dbesc($perm['deny_gid']), dbesc($resource_id), intval($page_owner_uid));
         }
         $item_private = $str_contact_allow || $str_group_allow || $str_contact_deny || $str_group_deny ? true : false;
         $old_is_nsfw = $p[0]['is_nsfw'];
         if ($old_is_nsfw != $is_nsfw) {
             $r = q("update photo set is_nsfw = %d where resource_id = '%s' and uid = %d", intval($is_nsfw), dbesc($resource_id), intval($page_owner_uid));
         }
         /* Don't make the item visible if the only change was the album name */
         $visibility = 0;
         if ($p[0]['description'] !== $desc || strlen($rawtags)) {
             $visibility = 1;
         }
         if (!$item_id) {
             $item_id = photos_create_item(\App::$data['channel'], get_observer_hash(), $p[0], $visibility);
         }
         if ($item_id) {
             $r = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($item_id), intval($page_owner_uid));
             if ($r) {
                 $old_tag = $r[0]['tag'];
                 $old_inform = $r[0]['inform'];
             }
         }
         // make sure the linked item has the same permissions as the photo regardless of any other changes
         $x = q("update item set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', item_private = %d\n\t\t\t\twhere id = %d", dbesc($perm['allow_cid']), dbesc($perm['allow_gid']), dbesc($perm['deny_cid']), dbesc($perm['deny_gid']), intval($acl->is_private()), intval($item_id));
         // make sure the attach has the same permissions as the photo regardless of any other changes
         $x = q("update attach set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where hash = '%s' and uid = %d and is_photo = 1", dbesc($perm['allow_cid']), dbesc($perm['allow_gid']), dbesc($perm['deny_cid']), dbesc($perm['deny_gid']), dbesc($resource_id), intval($page_owner_uid));
         if (strlen($rawtags)) {
             $str_tags = '';
             $inform = '';
             // if the new tag doesn't have a namespace specifier (@foo or #foo) give it a mention
             $x = substr($rawtags, 0, 1);
             if ($x !== '@' && $x !== '#') {
                 $rawtags = '@' . $rawtags;
             }
             require_once 'include/text.php';
             $profile_uid = \App::$profile['profile_uid'];
             $results = linkify_tags($a, $rawtags, local_channel() ? local_channel() : $profile_uid);
             $success = $results['success'];
             $post_tags = array();
             foreach ($results as $result) {
                 $success = $result['success'];
                 if ($success['replaced']) {
                     $post_tags[] = array('uid' => $profile_uid, 'ttype' => $success['termtype'], 'otype' => TERM_OBJ_POST, 'term' => $success['term'], 'url' => $success['url']);
                 }
             }
             $r = q("select * from item where id = %d and uid = %d limit 1", intval($item_id), intval($page_owner_uid));
             if ($r) {
                 $r = fetch_post_tags($r, true);
                 $datarray = $r[0];
                 if ($post_tags) {
                     if (!array_key_exists('term', $datarray) || !is_array($datarray['term'])) {
                         $datarray['term'] = $post_tags;
                     } else {
                         $datarray['term'] = array_merge($datarray['term'], $post_tags);
                     }
                 }
                 item_store_update($datarray, $execflag);
             }
         }
         $sync = attach_export_data(\App::$data['channel'], $resource_id);
         if ($sync) {
             build_sync_packet($page_owner_uid, array('file' => array($sync)));
         }
         goaway(z_root() . '/' . $_SESSION['photo_return']);
         return;
         // NOTREACHED
     }
     /**
      * default post action - upload a photo
      */
     $channel = \App::$data['channel'];
     $observer = \App::$data['observer'];
     $_REQUEST['source'] = 'photos';
     require_once 'include/attach.php';
     if (!local_channel()) {
         $_REQUEST['contact_allow'] = expand_acl($channel['channel_allow_cid']);
         $_REQUEST['group_allow'] = expand_acl($channel['channel_allow_gid']);
         $_REQUEST['contact_deny'] = expand_acl($channel['channel_deny_cid']);
         $_REQUEST['group_deny'] = expand_acl($channel['channel_deny_gid']);
     }
     $r = attach_store($channel, get_observer_hash(), '', $_REQUEST);
     if (!$r['success']) {
         notice($r['message'] . EOL);
     }
     if ($_REQUEST['newalbum']) {
         goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . bin2hex($_REQUEST['newalbum']));
     } else {
         goaway(z_root() . '/photos/' . \App::$data['channel']['channel_address'] . '/album/' . bin2hex(datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y')));
     }
 }
Beispiel #10
0
/**
 * @brief
 *
 * @param array $channel
 * @param array $observer
 * @param array $args
 * @return array
 */
function photo_upload($channel, $observer, $args)
{
    $ret = array('success' => false);
    $channel_id = $channel['channel_id'];
    $account_id = $channel['channel_account_id'];
    if (!perm_is_allowed($channel_id, $observer['xchan_hash'], 'write_storage')) {
        $ret['message'] = t('Permission denied.');
        return $ret;
    }
    //	call_hooks('photo_upload_begin', $args);
    /*
     * Determine the album to use
     */
    $album = $args['album'];
    if (intval($args['visible']) || $args['visible'] === 'true') {
        $visible = 1;
    } else {
        $visible = 0;
    }
    $deliver = true;
    if (array_key_exists('deliver', $args)) {
        $deliver = intval($args['deliver']);
    }
    // Set to default channel permissions. If the parent directory (album) has permissions set,
    // use those instead. If we have specific permissions supplied, they take precedence over
    // all other settings. 'allow_cid' being passed from an external source takes priority over channel settings.
    // ...messy... needs re-factoring once the photos/files integration stabilises
    $acl = new Zotlabs\Access\AccessList($channel);
    if (array_key_exists('directory', $args) && $args['directory']) {
        $acl->set($args['directory']);
    }
    if (array_key_exists('allow_cid', $args)) {
        $acl->set($args);
    }
    if (array_key_exists('group_allow', $args) || array_key_exists('contact_allow', $args) || array_key_exists('group_deny', $args) || array_key_exists('contact_deny', $args)) {
        $acl->set_from_array($args);
    }
    $ac = $acl->get();
    $os_storage = 0;
    if ($args['os_path'] && $args['getimagesize']) {
        $imagedata = @file_get_contents($args['os_path']);
        $filename = $args['filename'];
        $filesize = strlen($imagedata);
        // this is going to be deleted if it exists
        $src = '/tmp/deletemenow';
        $type = $args['getimagesize']['mime'];
        $os_storage = 1;
    } elseif ($args['data'] || $args['content']) {
        // allow an import from a binary string representing the image.
        // This bypasses the upload step and max size limit checking
        $imagedata = $args['content'] ? $args['content'] : $args['data'];
        $filename = $args['filename'];
        $filesize = strlen($imagedata);
        // this is going to be deleted if it exists
        $src = '/tmp/deletemenow';
        $type = $args['mimetype'] ? $args['mimetype'] : $args['type'];
    } else {
        $f = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => '');
        //		call_hooks('photo_upload_file',$f);
        if (x($f, 'src') && x($f, 'filesize')) {
            $src = $f['src'];
            $filename = $f['filename'];
            $filesize = $f['filesize'];
            $type = $f['type'];
        } else {
            $src = $_FILES['userfile']['tmp_name'];
            $filename = basename($_FILES['userfile']['name']);
            $filesize = intval($_FILES['userfile']['size']);
            $type = $_FILES['userfile']['type'];
        }
        if (!$type) {
            $type = guess_image_type($filename);
        }
        logger('photo_upload: received file: ' . $filename . ' as ' . $src . ' (' . $type . ') ' . $filesize . ' bytes', LOGGER_DEBUG);
        $maximagesize = get_config('system', 'maximagesize');
        if ($maximagesize && $filesize > $maximagesize) {
            $ret['message'] = sprintf(t('Image exceeds website size limit of %lu bytes'), $maximagesize);
            @unlink($src);
            call_hooks('photo_upload_end', $ret);
            return $ret;
        }
        if (!$filesize) {
            $ret['message'] = t('Image file is empty.');
            @unlink($src);
            call_hooks('photo_post_end', $ret);
            return $ret;
        }
        logger('photo_upload: loading the contents of ' . $src, LOGGER_DEBUG);
        $imagedata = @file_get_contents($src);
    }
    $r = q("select sum(filesize) as total from photo where aid = %d and imgscale = 0 ", intval($account_id));
    $limit = engr_units_to_bytes(service_class_fetch($channel_id, 'photo_upload_limit'));
    if ($r && $limit !== false && $r[0]['total'] + strlen($imagedata) > $limit) {
        $ret['message'] = upgrade_message();
        @unlink($src);
        call_hooks('photo_post_end', $ret);
        return $ret;
    }
    $ph = photo_factory($imagedata, $type);
    if (!$ph->is_valid()) {
        $ret['message'] = t('Unable to process image');
        logger('photo_upload: unable to process image');
        @unlink($src);
        call_hooks('photo_upload_end', $ret);
        return $ret;
    }
    $exif = $ph->orient($args['os_path'] ? $args['os_path'] : $src);
    @unlink($src);
    $max_length = get_config('system', 'max_image_length');
    if (!$max_length) {
        $max_length = MAX_IMAGE_LENGTH;
    }
    if ($max_length > 0) {
        $ph->scaleImage($max_length);
    }
    $width = $ph->getWidth();
    $height = $ph->getHeight();
    $smallest = 0;
    $photo_hash = $args['resource_id'] ? $args['resource_id'] : photo_new_resource();
    $visitor = '';
    if ($channel['channel_hash'] !== $observer['xchan_hash']) {
        $visitor = $observer['xchan_hash'];
    }
    $errors = false;
    $p = array('aid' => $account_id, 'uid' => $channel_id, 'xchan' => $visitor, 'resource_id' => $photo_hash, 'filename' => $filename, 'album' => $album, 'imgscale' => 0, 'photo_usage' => PHOTO_NORMAL, 'allow_cid' => $ac['allow_cid'], 'allow_gid' => $ac['allow_gid'], 'deny_cid' => $ac['deny_cid'], 'deny_gid' => $ac['deny_gid'], 'os_storage' => $os_storage, 'os_path' => $args['os_path']);
    if ($args['created']) {
        $p['created'] = $args['created'];
    }
    if ($args['edited']) {
        $p['edited'] = $args['edited'];
    }
    if ($args['title']) {
        $p['title'] = $args['title'];
    }
    if ($args['description']) {
        $p['description'] = $args['description'];
    }
    $link = array();
    $r0 = $ph->save($p);
    $link[0] = array('rel' => 'alternate', 'type' => 'text/html', 'href' => z_root() . '/photo/' . $photo_hash . '-0.' . $ph->getExt(), 'width' => $ph->getWidth(), 'height' => $ph->getHeight());
    if (!$r0) {
        $errors = true;
    }
    unset($p['os_storage']);
    unset($p['os_path']);
    if (($width > 1024 || $height > 1024) && !$errors) {
        $ph->scaleImage(1024);
    }
    $p['imgscale'] = 1;
    $r1 = $ph->save($p);
    $link[1] = array('rel' => 'alternate', 'type' => 'text/html', 'href' => z_root() . '/photo/' . $photo_hash . '-1.' . $ph->getExt(), 'width' => $ph->getWidth(), 'height' => $ph->getHeight());
    if (!$r1) {
        $errors = true;
    }
    if (($width > 640 || $height > 640) && !$errors) {
        $ph->scaleImage(640);
    }
    $p['imgscale'] = 2;
    $r2 = $ph->save($p);
    $link[2] = array('rel' => 'alternate', 'type' => 'text/html', 'href' => z_root() . '/photo/' . $photo_hash . '-2.' . $ph->getExt(), 'width' => $ph->getWidth(), 'height' => $ph->getHeight());
    if (!$r2) {
        $errors = true;
    }
    if (($width > 320 || $height > 320) && !$errors) {
        $ph->scaleImage(320);
    }
    $p['imgscale'] = 3;
    $r3 = $ph->save($p);
    $link[3] = array('rel' => 'alternate', 'type' => 'text/html', 'href' => z_root() . '/photo/' . $photo_hash . '-3.' . $ph->getExt(), 'width' => $ph->getWidth(), 'height' => $ph->getHeight());
    if (!$r3) {
        $errors = true;
    }
    if ($errors) {
        q("delete from photo where resource_id = '%s' and uid = %d", dbesc($photo_hash), intval($channel_id));
        $ret['message'] = t('Photo storage failed.');
        logger('photo_upload: photo store failed.');
        call_hooks('photo_upload_end', $ret);
        return $ret;
    }
    $item_hidden = $visible ? 0 : 1;
    $lat = $lon = null;
    if ($exif && $exif['GPS']) {
        if (feature_enabled($channel_id, 'photo_location')) {
            $lat = getGps($exif['GPS']['GPSLatitude'], $exif['GPS']['GPSLatitudeRef']);
            $lon = getGps($exif['GPS']['GPSLongitude'], $exif['GPS']['GPSLongitudeRef']);
        }
    }
    $title = $args['description'] ? $args['description'] : $args['filename'];
    $large_photos = feature_enabled($channel['channel_id'], 'large_photos');
    linkify_tags($a, $args['body'], $channel_id);
    if ($large_photos) {
        $scale = 1;
        $width = $link[1]['width'];
        $height = $link[1]['height'];
        $tag = $r1 ? '[zmg=' . $width . 'x' . $height . ']' : '[zmg]';
    } else {
        $scale = 2;
        $width = $link[2]['width'];
        $height = $link[2]['height'];
        $tag = $r2 ? '[zmg=' . $width . 'x' . $height . ']' : '[zmg]';
    }
    $author_link = '[zrl=' . z_root() . '/channel/' . $channel['channel_address'] . ']' . $channel['channel_name'] . '[/zrl]';
    $photo_link = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']' . t('a new photo') . '[/zrl]';
    $album_link = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/album/' . bin2hex($album) . ']' . (strlen($album) ? $album : '/') . '[/zrl]';
    $activity_format = sprintf(t('%1$s posted %2$s to %3$s', 'photo_upload'), $author_link, $photo_link, $album_link);
    $summary = ($args['body'] ? $args['body'] : '') . '[footer]' . $activity_format . '[/footer]';
    $obj_body = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']' . $tag . z_root() . "/photo/{$photo_hash}-{$scale}." . $ph->getExt() . '[/zmg]' . '[/zrl]';
    // Create item object
    $object = array('type' => ACTIVITY_OBJ_PHOTO, 'title' => $title, 'created' => $p['created'], 'edited' => $p['edited'], 'id' => z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash, 'link' => $link, 'body' => $obj_body);
    $target = array('type' => ACTIVITY_OBJ_ALBUM, 'title' => $album ? $album : '/', 'id' => z_root() . '/photos/' . $channel['channel_address'] . '/album/' . bin2hex($album));
    // Create item container
    if ($args['item']) {
        foreach ($args['item'] as $i) {
            $item = get_item_elements($i);
            $force = false;
            if ($item['mid'] === $item['parent_mid']) {
                $item['body'] = $summary;
                $item['obj_type'] = ACTIVITY_OBJ_PHOTO;
                $item['obj'] = json_encode($object);
                $item['tgt_type'] = ACTIVITY_OBJ_ALBUM;
                $item['target'] = json_encode($target);
                if ($item['author_xchan'] === $channel['channel_hash']) {
                    $item['sig'] = base64url_encode(rsa_sign($item['body'], $channel['channel_prvkey']));
                    $item['item_verified'] = 1;
                } else {
                    $item['sig'] = '';
                }
                $force = true;
            }
            $r = q("select id, edited from item where mid = '%s' and uid = %d limit 1", dbesc($item['mid']), intval($channel['channel_id']));
            if ($r) {
                if ($item['edited'] > $r[0]['edited'] || $force) {
                    $item['id'] = $r[0]['id'];
                    $item['uid'] = $channel['channel_id'];
                    item_store_update($item, false, $deliver);
                    continue;
                }
            } else {
                $item['aid'] = $channel['channel_account_id'];
                $item['uid'] = $channel['channel_id'];
                $item_result = item_store($item, false, $deliver);
            }
        }
    } else {
        $mid = item_message_id();
        $arr = array();
        if ($lat && $lon) {
            $arr['coord'] = $lat . ' ' . $lon;
        }
        $arr['aid'] = $account_id;
        $arr['uid'] = $channel_id;
        $arr['mid'] = $mid;
        $arr['parent_mid'] = $mid;
        $arr['item_hidden'] = $item_hidden;
        $arr['resource_type'] = 'photo';
        $arr['resource_id'] = $photo_hash;
        $arr['owner_xchan'] = $channel['channel_hash'];
        $arr['author_xchan'] = $observer['xchan_hash'];
        $arr['title'] = $title;
        $arr['allow_cid'] = $ac['allow_cid'];
        $arr['allow_gid'] = $ac['allow_gid'];
        $arr['deny_cid'] = $ac['deny_cid'];
        $arr['deny_gid'] = $ac['deny_gid'];
        $arr['verb'] = ACTIVITY_POST;
        $arr['obj_type'] = ACTIVITY_OBJ_PHOTO;
        $arr['obj'] = json_encode($object);
        $arr['tgt_type'] = ACTIVITY_OBJ_ALBUM;
        $arr['target'] = json_encode($target);
        $arr['item_wall'] = 1;
        $arr['item_origin'] = 1;
        $arr['item_thread_top'] = 1;
        $arr['item_private'] = intval($acl->is_private());
        $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid'];
        $arr['body'] = $summary;
        // this one is tricky because the item and the photo have the same permissions, those of the photo.
        // Use the channel read_stream permissions to get the correct public_policy for the item and recalculate the
        // private flag accordingly. This may cause subtle bugs due to custom permissions roles. We want to use
        // public policy when federating items to other sites, but should probably ignore them when accessing the item
        // in the photos pages - using the photos permissions instead. We need the public policy to keep the photo
        // linked item from leaking into the feed when somebody has a channel with read_stream restrictions.
        $arr['public_policy'] = map_scope($channel['channel_r_stream'], true);
        if ($arr['public_policy']) {
            $arr['item_private'] = 1;
        }
        $result = item_store($arr, false, $deliver);
        $item_id = $result['item_id'];
        if ($visible && $deliver) {
            Zotlabs\Daemon\Master::Summon(array('Notifier', 'wall-new', $item_id));
        }
    }
    $ret['success'] = true;
    $ret['item'] = $arr;
    $ret['body'] = $obj_body;
    $ret['resource_id'] = $photo_hash;
    $ret['photoitem_id'] = $item_id;
    call_hooks('photo_upload_end', $ret);
    return $ret;
}
Beispiel #11
0
function item_post(&$a)
{
    // This will change. Figure out who the observer is and whether or not
    // they have permission to post here. Else ignore the post.
    if (!local_channel() && !remote_channel() && !x($_REQUEST, 'commenter')) {
        return;
    }
    require_once 'include/security.php';
    $uid = local_channel();
    $channel = null;
    $observer = null;
    /**
     * Is this a reply to something?
     */
    $parent = x($_REQUEST, 'parent') ? intval($_REQUEST['parent']) : 0;
    $parent_mid = x($_REQUEST, 'parent_mid') ? trim($_REQUEST['parent_mid']) : '';
    $remote_xchan = x($_REQUEST, 'remote_xchan') ? trim($_REQUEST['remote_xchan']) : false;
    $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($remote_xchan));
    if ($r) {
        $remote_observer = $r[0];
    } else {
        $remote_xchan = $remote_observer = false;
    }
    $profile_uid = x($_REQUEST, 'profile_uid') ? intval($_REQUEST['profile_uid']) : 0;
    require_once 'include/identity.php';
    $sys = get_sys_channel();
    if ($sys && $profile_uid && $sys['channel_id'] == $profile_uid && is_site_admin()) {
        $uid = intval($sys['channel_id']);
        $channel = $sys;
        $observer = $sys;
    }
    if (x($_REQUEST, 'dropitems')) {
        require_once 'include/items.php';
        $arr_drop = explode(',', $_REQUEST['dropitems']);
        drop_items($arr_drop);
        $json = array('success' => 1);
        echo json_encode($json);
        killme();
    }
    call_hooks('post_local_start', $_REQUEST);
    //	 logger('postvars ' . print_r($_REQUEST,true), LOGGER_DATA);
    $api_source = x($_REQUEST, 'api_source') && $_REQUEST['api_source'] ? true : false;
    $consensus = intval($_REQUEST['consensus']);
    // 'origin' (if non-zero) indicates that this network is where the message originated,
    // for the purpose of relaying comments to other conversation members.
    // If using the API from a device (leaf node) you must set origin to 1 (default) or leave unset.
    // If the API is used from another network with its own distribution
    // and deliveries, you may wish to set origin to 0 or false and allow the other
    // network to relay comments.
    // If you are unsure, it is prudent (and important) to leave it unset.
    $origin = $api_source && array_key_exists('origin', $_REQUEST) ? intval($_REQUEST['origin']) : 1;
    // To represent message-ids on other networks - this will create an item_id record
    $namespace = $api_source && array_key_exists('namespace', $_REQUEST) ? strip_tags($_REQUEST['namespace']) : '';
    $remote_id = $api_source && array_key_exists('remote_id', $_REQUEST) ? strip_tags($_REQUEST['remote_id']) : '';
    $owner_hash = null;
    $message_id = x($_REQUEST, 'message_id') && $api_source ? strip_tags($_REQUEST['message_id']) : '';
    $created = x($_REQUEST, 'created') ? datetime_convert(date_default_timezone_get(), 'UTC', $_REQUEST['created']) : datetime_convert();
    $post_id = x($_REQUEST, 'post_id') ? intval($_REQUEST['post_id']) : 0;
    $app = x($_REQUEST, 'source') ? strip_tags($_REQUEST['source']) : '';
    $return_path = x($_REQUEST, 'return') ? $_REQUEST['return'] : '';
    $preview = x($_REQUEST, 'preview') ? intval($_REQUEST['preview']) : 0;
    $categories = x($_REQUEST, 'category') ? escape_tags($_REQUEST['category']) : '';
    $webpage = x($_REQUEST, 'webpage') ? intval($_REQUEST['webpage']) : 0;
    $pagetitle = x($_REQUEST, 'pagetitle') ? escape_tags(urlencode($_REQUEST['pagetitle'])) : '';
    $layout_mid = x($_REQUEST, 'layout_mid') ? escape_tags($_REQUEST['layout_mid']) : '';
    $plink = x($_REQUEST, 'permalink') ? escape_tags($_REQUEST['permalink']) : '';
    $obj_type = x($_REQUEST, 'obj_type') ? escape_tags($_REQUEST['obj_type']) : ACTIVITY_OBJ_NOTE;
    // allow API to bulk load a bunch of imported items with sending out a bunch of posts.
    $nopush = x($_REQUEST, 'nopush') ? intval($_REQUEST['nopush']) : 0;
    /*
     * Check service class limits
     */
    if ($uid && !x($_REQUEST, 'parent') && !x($_REQUEST, 'post_id')) {
        $ret = item_check_service_class($uid, $_REQUEST['webpage'] == ITEM_TYPE_WEBPAGE ? true : false);
        if (!$ret['success']) {
            notice(t($ret['message']) . EOL);
            if (x($_REQUEST, 'return')) {
                goaway(z_root() . "/" . $return_path);
            }
            killme();
        }
    }
    if ($pagetitle) {
        require_once 'library/urlify/URLify.php';
        $pagetitle = strtolower(URLify::transliterate($pagetitle));
    }
    $item_flags = $item_restrict = 0;
    $route = '';
    $parent_item = null;
    $parent_contact = null;
    $thr_parent = '';
    $parid = 0;
    $r = false;
    if ($parent || $parent_mid) {
        if (!x($_REQUEST, 'type')) {
            $_REQUEST['type'] = 'net-comment';
        }
        if ($obj_type == ACTIVITY_OBJ_POST) {
            $obj_type = ACTIVITY_OBJ_COMMENT;
        }
        if ($parent) {
            $r = q("SELECT * FROM `item` WHERE `id` = %d LIMIT 1", intval($parent));
        } elseif ($parent_mid && $uid) {
            // This is coming from an API source, and we are logged in
            $r = q("SELECT * FROM `item` WHERE `mid` = '%s' AND `uid` = %d LIMIT 1", dbesc($parent_mid), intval($uid));
        }
        // if this isn't the real parent of the conversation, find it
        if ($r !== false && count($r)) {
            $parid = $r[0]['parent'];
            $parent_mid = $r[0]['mid'];
            if ($r[0]['id'] != $r[0]['parent']) {
                $r = q("SELECT * FROM `item` WHERE `id` = `parent` AND `parent` = %d LIMIT 1", intval($parid));
            }
        }
        if ($r === false || !count($r)) {
            notice(t('Unable to locate original post.') . EOL);
            if (x($_REQUEST, 'return')) {
                goaway(z_root() . "/" . $return_path);
            }
            killme();
        }
        // can_comment_on_post() needs info from the following xchan_query
        xchan_query($r);
        $parent_item = $r[0];
        $parent = $r[0]['id'];
        // multi-level threading - preserve the info but re-parent to our single level threading
        $thr_parent = $parent_mid;
        $route = $parent_item['route'];
    }
    if (!$observer) {
        $observer = App::get_observer();
    }
    if ($parent) {
        logger('mod_item: item_post parent=' . $parent);
        $can_comment = false;
        if (array_key_exists('owner', $parent_item) && intval($parent_item['owner']['abook_self'])) {
            $can_comment = perm_is_allowed($profile_uid, $observer['xchan_hash'], 'post_comments');
        } else {
            $can_comment = can_comment_on_post($observer['xchan_hash'], $parent_item);
        }
        if (!$can_comment) {
            notice(t('Permission denied.') . EOL);
            if (x($_REQUEST, 'return')) {
                goaway(z_root() . "/" . $return_path);
            }
            killme();
        }
    } else {
        if (!perm_is_allowed($profile_uid, $observer['xchan_hash'], $webpage ? 'write_pages' : 'post_wall')) {
            notice(t('Permission denied.') . EOL);
            if (x($_REQUEST, 'return')) {
                goaway(z_root() . "/" . $return_path);
            }
            killme();
        }
    }
    // is this an edited post?
    $orig_post = null;
    if ($namespace && $remote_id) {
        // It wasn't an internally generated post - see if we've got an item matching this remote service id
        $i = q("select iid from item_id where service = '%s' and sid = '%s' limit 1", dbesc($namespace), dbesc($remote_id));
        if ($i) {
            $post_id = $i[0]['iid'];
        }
    }
    $iconfig = null;
    if ($post_id) {
        $i = q("SELECT * FROM `item` WHERE `uid` = %d AND `id` = %d LIMIT 1", intval($profile_uid), intval($post_id));
        if (!count($i)) {
            killme();
        }
        $orig_post = $i[0];
        $iconfig = q("select * from iconfig where iid = %d", intval($post_id));
    }
    if (!$channel) {
        if ($uid && $uid == $profile_uid) {
            $channel = App::get_channel();
        } else {
            // posting as yourself but not necessarily to a channel you control
            $r = q("select * from channel left join account on channel_account_id = account_id where channel_id = %d LIMIT 1", intval($profile_uid));
            if ($r) {
                $channel = $r[0];
            }
        }
    }
    if (!$channel) {
        logger("mod_item: no channel.");
        if (x($_REQUEST, 'return')) {
            goaway(z_root() . "/" . $return_path);
        }
        killme();
    }
    $owner_xchan = null;
    $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($channel['channel_hash']));
    if ($r && count($r)) {
        $owner_xchan = $r[0];
    } else {
        logger("mod_item: no owner.");
        if (x($_REQUEST, 'return')) {
            goaway(z_root() . "/" . $return_path);
        }
        killme();
    }
    $walltowall = false;
    $walltowall_comment = false;
    if ($remote_xchan) {
        $observer = $remote_observer;
    }
    if ($observer) {
        logger('mod_item: post accepted from ' . $observer['xchan_name'] . ' for ' . $owner_xchan['xchan_name'], LOGGER_DEBUG);
        // wall-to-wall detection.
        // For top-level posts, if the author and owner are different it's a wall-to-wall
        // For comments, We need to additionally look at the parent and see if it's a wall post that originated locally.
        if ($observer['xchan_name'] != $owner_xchan['xchan_name']) {
            if ($parent_item && ($parent_item['item_wall'] && $parent_item['item_origin'])) {
                $walltowall_comment = true;
                $walltowall = true;
            }
            if (!$parent) {
                $walltowall = true;
            }
        }
    }
    $acl = new Zotlabs\Access\AccessList($channel);
    $public_policy = x($_REQUEST, 'public_policy') ? escape_tags($_REQUEST['public_policy']) : map_scope($channel['channel_r_stream'], true);
    if ($webpage) {
        $public_policy = '';
    }
    if ($public_policy) {
        $private = 1;
    }
    if ($orig_post) {
        $private = 0;
        // webpages are allowed to change ACLs after the fact. Normal conversation items aren't.
        if ($webpage) {
            $acl->set_from_array($_REQUEST);
        } else {
            $acl->set($orig_post);
            $public_policy = $orig_post['public_policy'];
            $private = $orig_post['item_private'];
        }
        if ($private || $public_policy || $acl->is_private()) {
            $private = 1;
        }
        $location = $orig_post['location'];
        $coord = $orig_post['coord'];
        $verb = $orig_post['verb'];
        $app = $orig_post['app'];
        $title = escape_tags(trim($_REQUEST['title']));
        $body = trim($_REQUEST['body']);
        $item_flags = $orig_post['item_flags'];
        $item_origin = $orig_post['item_origin'];
        $item_unseen = $orig_post['item_unseen'];
        $item_starred = $orig_post['item_starred'];
        $item_uplink = $orig_post['item_uplink'];
        $item_consensus = $orig_post['item_consensus'];
        $item_wall = $orig_post['item_wall'];
        $item_thread_top = $orig_post['item_thread_top'];
        $item_notshown = $orig_post['item_notshown'];
        $item_nsfw = $orig_post['item_nsfw'];
        $item_relay = $orig_post['item_relay'];
        $item_mentionsme = $orig_post['item_mentionsme'];
        $item_nocomment = $orig_post['item_nocomment'];
        $item_obscured = $orig_post['item_obscured'];
        $item_verified = $orig_post['item_verified'];
        $item_retained = $orig_post['item_retained'];
        $item_rss = $orig_post['item_rss'];
        $item_deleted = $orig_post['item_deleted'];
        $item_type = $orig_post['item_type'];
        $item_hidden = $orig_post['item_hidden'];
        $item_unpublished = $orig_post['item_unpublished'];
        $item_delayed = $orig_post['item_delayed'];
        $item_pending_remove = $orig_post['item_pending_remove'];
        $item_blocked = $orig_post['item_blocked'];
        $postopts = $orig_post['postopts'];
        $created = $orig_post['created'];
        $mid = $orig_post['mid'];
        $parent_mid = $orig_post['parent_mid'];
        $plink = $orig_post['plink'];
    } else {
        if (!$walltowall) {
            if (array_key_exists('contact_allow', $_REQUEST) || array_key_exists('group_allow', $_REQUEST) || array_key_exists('contact_deny', $_REQUEST) || array_key_exists('group_deny', $_REQUEST)) {
                $acl->set_from_array($_REQUEST);
            } elseif (!$api_source) {
                // if no ACL has been defined and we aren't using the API, the form
                // didn't send us any parameters. This means there's no ACL or it has
                // been reset to the default audience.
                // If $api_source is set and there are no ACL parameters, we default
                // to the channel permissions which were set in the ACL contructor.
                $acl->set(array('allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => ''));
            }
        }
        $location = notags(trim($_REQUEST['location']));
        $coord = notags(trim($_REQUEST['coord']));
        $verb = notags(trim($_REQUEST['verb']));
        $title = escape_tags(trim($_REQUEST['title']));
        $body = trim($_REQUEST['body']);
        $body .= trim($_REQUEST['attachment']);
        $postopts = '';
        $private = intval($acl->is_private() || $public_policy);
        // If this is a comment, set the permissions from the parent.
        if ($parent_item) {
            $private = 0;
            $acl->set($parent_item);
            $private = intval($acl->is_private() || $parent_item['item_private']);
            $public_policy = $parent_item['public_policy'];
            $owner_hash = $parent_item['owner_xchan'];
        }
        if (!strlen($body)) {
            if ($preview) {
                killme();
            }
            info(t('Empty post discarded.') . EOL);
            if (x($_REQUEST, 'return')) {
                goaway(z_root() . "/" . $return_path);
            }
            killme();
        }
    }
    $expires = NULL_DATE;
    if (feature_enabled($profile_uid, 'content_expire')) {
        if (x($_REQUEST, 'expire')) {
            $expires = datetime_convert(date_default_timezone_get(), 'UTC', $_REQUEST['expire']);
            if ($expires <= datetime_convert()) {
                $expires = NULL_DATE;
            }
        }
    }
    $mimetype = notags(trim($_REQUEST['mimetype']));
    if (!$mimetype) {
        $mimetype = 'text/bbcode';
    }
    if ($preview) {
        $body = z_input_filter($profile_uid, $body, $mimetype);
    }
    // Verify ability to use html or php!!!
    $execflag = false;
    if ($mimetype !== 'text/bbcode') {
        $z = q("select account_id, account_roles, channel_pageflags from account left join channel on channel_account_id = account_id where channel_id = %d limit 1", intval($profile_uid));
        if ($z && ($z[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE || $z[0]['channel_pageflags'] & PAGE_ALLOWCODE)) {
            if ($uid && get_account_id() == $z[0]['account_id']) {
                $execflag = true;
            } else {
                notice(t('Executable content type not permitted to this channel.') . EOL);
                if (x($_REQUEST, 'return')) {
                    goaway(z_root() . "/" . $return_path);
                }
                killme();
            }
        }
    }
    $gacl = $acl->get();
    $str_contact_allow = $gacl['allow_cid'];
    $str_group_allow = $gacl['allow_gid'];
    $str_contact_deny = $gacl['deny_cid'];
    $str_group_deny = $gacl['deny_gid'];
    if ($mimetype === 'text/bbcode') {
        require_once 'include/text.php';
        // Markdown doesn't work correctly. Do not re-enable unless you're willing to fix it and support it.
        // Sample that will probably give you grief - you must preserve the linebreaks
        // and provide the correct markdown interpretation and you cannot allow unfiltered HTML
        // Markdown
        // ========
        //
        // **bold** abcde
        // fghijkl
        // *italic*
        // <img src="javascript:alert('hacked');" />
        //		if($uid && $uid == $profile_uid && feature_enabled($uid,'markdown')) {
        //			require_once('include/bb2diaspora.php');
        //			$body = escape_tags(trim($body));
        //			$body = str_replace("\n",'<br />', $body);
        //			$body = preg_replace_callback('/\[share(.*?)\]/ism','share_shield',$body);
        //			$body = diaspora2bb($body,true);
        //			$body = preg_replace_callback('/\[share(.*?)\]/ism','share_unshield',$body);
        //		}
        // BBCODE alert: the following functions assume bbcode input
        // and will require alternatives for alternative content-types (text/html, text/markdown, text/plain, etc.)
        // we may need virtual or template classes to implement the possible alternatives
        // Work around doubled linefeeds in Tinymce 3.5b2
        // First figure out if it's a status post that would've been
        // created using tinymce. Otherwise leave it alone.
        $plaintext = true;
        //		$plaintext = ((feature_enabled($profile_uid,'richtext')) ? false : true);
        //		if((! $parent) && (! $api_source) && (! $plaintext)) {
        //			$body = fix_mce_lf($body);
        //		}
        // If we're sending a private top-level message with a single @-taggable channel as a recipient, @-tag it, if our pconfig is set.
        if (!$parent && get_pconfig($profile_uid, 'system', 'tagifonlyrecip') && substr_count($str_contact_allow, '<') == 1 && $str_group_allow == '' && $str_contact_deny == '' && $str_group_deny == '') {
            $x = q("select abook_id, abook_their_perms from abook where abook_xchan = '%s' and abook_channel = %d limit 1", dbesc(str_replace(array('<', '>'), array('', ''), $str_contact_allow)), intval($profile_uid));
            if ($x && $x[0]['abook_their_perms'] & PERMS_W_TAGWALL) {
                $body .= "\n\n@group+" . $x[0]['abook_id'] . "\n";
            }
        }
        /**
         * fix naked links by passing through a callback to see if this is a red site
         * (already known to us) which will get a zrl, otherwise link with url, add bookmark tag to both.
         * First protect any url inside certain bbcode tags so we don't double link it.
         */
        $body = preg_replace_callback('/\\[code(.*?)\\[\\/(code)\\]/ism', 'red_escape_codeblock', $body);
        $body = preg_replace_callback('/\\[url(.*?)\\[\\/(url)\\]/ism', 'red_escape_codeblock', $body);
        $body = preg_replace_callback('/\\[zrl(.*?)\\[\\/(zrl)\\]/ism', 'red_escape_codeblock', $body);
        $body = preg_replace_callback("/([^\\]\\='" . '"' . "\\/]|^|\\#\\^)(https?\\:\\/\\/[a-zA-Z0-9\\:\\/\\-\\?\\&\\;\\.\\=\\@\\_\\~\\#\\%\$\\!\\+\\,]+)/ism", 'red_zrl_callback', $body);
        $body = preg_replace_callback('/\\[\\$b64zrl(.*?)\\[\\/(zrl)\\]/ism', 'red_unescape_codeblock', $body);
        $body = preg_replace_callback('/\\[\\$b64url(.*?)\\[\\/(url)\\]/ism', 'red_unescape_codeblock', $body);
        $body = preg_replace_callback('/\\[\\$b64code(.*?)\\[\\/(code)\\]/ism', 'red_unescape_codeblock', $body);
        // fix any img tags that should be zmg
        $body = preg_replace_callback('/\\[img(.*?)\\](.*?)\\[\\/img\\]/ism', 'red_zrlify_img_callback', $body);
        $body = bb_translate_video($body);
        /**
         * Fold multi-line [code] sequences
         */
        $body = preg_replace('/\\[\\/code\\]\\s*\\[code\\]/ism', "\n", $body);
        $body = scale_external_images($body, false);
        // Look for tags and linkify them
        $results = linkify_tags($a, $body, $uid ? $uid : $profile_uid);
        if ($results) {
            // Set permissions based on tag replacements
            set_linkified_perms($results, $str_contact_allow, $str_group_allow, $profile_uid, $parent_item, $private);
            $post_tags = array();
            foreach ($results as $result) {
                $success = $result['success'];
                if ($success['replaced']) {
                    $post_tags[] = array('uid' => $profile_uid, 'type' => $success['termtype'], 'otype' => TERM_OBJ_POST, 'term' => $success['term'], 'url' => $success['url']);
                }
            }
        }
        /**
         *
         * When a photo was uploaded into the message using the (profile wall) ajax 
         * uploader, The permissions are initially set to disallow anybody but the
         * owner from seeing it. This is because the permissions may not yet have been
         * set for the post. If it's private, the photo permissions should be set
         * appropriately. But we didn't know the final permissions on the post until
         * now. So now we'll look for links of uploaded photos and attachments that are in the
         * post and set them to the same permissions as the post itself.
         *
         * If the post was end-to-end encrypted we can't find images and attachments in the body,
         * use our media_str input instead which only contains these elements - but only do this
         * when encrypted content exists because the photo/attachment may have been removed from 
         * the post and we should keep it private. If it's encrypted we have no way of knowing
         * so we'll set the permissions regardless and realise that the media may not be 
         * referenced in the post. 
         *
         * What is preventing us from being able to upload photos into comments is dealing with
         * the photo and attachment permissions, since we don't always know who was in the 
         * distribution for the top level post.
         * 
         * We might be able to provide this functionality with a lot of fiddling:
         * - if the top level post is public (make the photo public)
         * - if the top level post was written by us or a wall post that belongs to us (match the top level post)
         * - if the top level post has privacy mentions, add those to the permissions.
         * - otherwise disallow the photo *or* make the photo public. This is the part that gets messy. 
         */
        if (!$preview) {
            fix_attached_photo_permissions($profile_uid, $owner_xchan['xchan_hash'], strpos($body, '[/crypt]') ? $_POST['media_str'] : $body, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
            fix_attached_file_permissions($channel, $observer['xchan_hash'], strpos($body, '[/crypt]') ? $_POST['media_str'] : $body, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
        }
        $attachments = '';
        $match = false;
        if (preg_match_all('/(\\[attachment\\](.*?)\\[\\/attachment\\])/', $body, $match)) {
            $attachments = array();
            $i = 0;
            foreach ($match[2] as $mtch) {
                $attach_link = '';
                $hash = substr($mtch, 0, strpos($mtch, ','));
                $rev = intval(substr($mtch, strpos($mtch, ',')));
                $r = attach_by_hash_nodata($hash, $rev);
                if ($r['success']) {
                    $attachments[] = array('href' => z_root() . '/attach/' . $r['data']['hash'], 'length' => $r['data']['filesize'], 'type' => $r['data']['filetype'], 'title' => urlencode($r['data']['filename']), 'revision' => $r['data']['revision']);
                }
                $ext = substr($r['data']['filename'], strrpos($r['data']['filename'], '.'));
                if (strpos($r['data']['filetype'], 'audio/') !== false) {
                    $attach_link = '[audio]' . z_root() . '/attach/' . $r['data']['hash'] . '/' . $r['data']['revision'] . ($ext ? $ext : '') . '[/audio]';
                } elseif (strpos($r['data']['filetype'], 'video/') !== false) {
                    $attach_link = '[video]' . z_root() . '/attach/' . $r['data']['hash'] . '/' . $r['data']['revision'] . ($ext ? $ext : '') . '[/video]';
                }
                $body = str_replace($match[1][$i], $attach_link, $body);
                $i++;
            }
        }
    }
    // BBCODE end alert
    if (strlen($categories)) {
        $cats = explode(',', $categories);
        foreach ($cats as $cat) {
            $post_tags[] = array('uid' => $profile_uid, 'type' => TERM_CATEGORY, 'otype' => TERM_OBJ_POST, 'term' => trim($cat), 'url' => $owner_xchan['xchan_url'] . '?f=&cat=' . urlencode(trim($cat)));
        }
    }
    if ($orig_post) {
        // preserve original tags
        $t = q("select * from term where oid = %d and otype = %d and uid = %d and type in ( %d, %d, %d )", intval($orig_post['id']), intval(TERM_OBJ_POST), intval($profile_uid), intval(TERM_UNKNOWN), intval(TERM_FILE), intval(TERM_COMMUNITYTAG));
        if ($t) {
            foreach ($t as $t1) {
                $post_tags[] = array('uid' => $profile_uid, 'type' => $t1['type'], 'otype' => TERM_OBJ_POST, 'term' => $t1['term'], 'url' => $t1['url']);
            }
        }
    }
    $item_unseen = local_channel() != $profile_uid ? 1 : 0;
    $item_wall = $post_type === 'wall' || $post_type === 'wall-comment' ? 1 : 0;
    $item_origin = $origin ? 1 : 0;
    $item_consensus = $consensus ? 1 : 0;
    // determine if this is a wall post
    if ($parent) {
        $item_wall = $parent_item['item_wall'];
    } else {
        if (!$webpage) {
            $item_wall = 1;
        }
    }
    if ($moderated) {
        $item_blocked = ITEM_MODERATED;
    }
    if (!strlen($verb)) {
        $verb = ACTIVITY_POST;
    }
    $notify_type = $parent ? 'comment-new' : 'wall-new';
    if (!$mid) {
        $mid = $message_id ? $message_id : item_message_id();
    }
    if (!$parent_mid) {
        $parent_mid = $mid;
    }
    if ($parent_item) {
        $parent_mid = $parent_item['mid'];
    }
    // Fallback so that we alway have a thr_parent
    if (!$thr_parent) {
        $thr_parent = $mid;
    }
    $datarray = array();
    $item_thread_top = !$parent ? 1 : 0;
    if (!$plink && $item_thread_top) {
        $plink = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $mid;
    }
    $datarray['aid'] = $channel['channel_account_id'];
    $datarray['uid'] = $profile_uid;
    $datarray['owner_xchan'] = $owner_hash ? $owner_hash : $owner_xchan['xchan_hash'];
    $datarray['author_xchan'] = $observer['xchan_hash'];
    $datarray['created'] = $created;
    $datarray['edited'] = $orig_post ? datetime_convert() : $created;
    $datarray['expires'] = $expires;
    $datarray['commented'] = $orig_post ? datetime_convert() : $created;
    $datarray['received'] = $orig_post ? datetime_convert() : $created;
    $datarray['changed'] = $orig_post ? datetime_convert() : $created;
    $datarray['mid'] = $mid;
    $datarray['parent_mid'] = $parent_mid;
    $datarray['mimetype'] = $mimetype;
    $datarray['title'] = $title;
    $datarray['body'] = $body;
    $datarray['app'] = $app;
    $datarray['location'] = $location;
    $datarray['coord'] = $coord;
    $datarray['verb'] = $verb;
    $datarray['obj_type'] = $obj_type;
    $datarray['allow_cid'] = $str_contact_allow;
    $datarray['allow_gid'] = $str_group_allow;
    $datarray['deny_cid'] = $str_contact_deny;
    $datarray['deny_gid'] = $str_group_deny;
    $datarray['item_private'] = $private;
    $datarray['item_wall'] = $item_wall;
    $datarray['attach'] = $attachments;
    $datarray['thr_parent'] = $thr_parent;
    $datarray['postopts'] = $postopts;
    $datarray['item_unseen'] = $item_unseen;
    $datarray['item_wall'] = $item_wall;
    $datarray['item_origin'] = $item_origin;
    $datarray['item_type'] = $webpage;
    $datarray['item_thread_top'] = $item_thread_top;
    $datarray['item_unseen'] = $item_unseen;
    $datarray['item_starred'] = $item_starred;
    $datarray['item_uplink'] = $item_uplink;
    $datarray['item_consensus'] = $item_consensus;
    $datarray['item_notshown'] = $item_notshown;
    $datarray['item_nsfw'] = $item_nsfw;
    $datarray['item_relay'] = $item_relay;
    $datarray['item_mentionsme'] = $item_mentionsme;
    $datarray['item_nocomment'] = $item_nocomment;
    $datarray['item_obscured'] = $item_obscured;
    $datarray['item_verified'] = $item_verified;
    $datarray['item_retained'] = $item_retained;
    $datarray['item_rss'] = $item_rss;
    $datarray['item_deleted'] = $item_deleted;
    $datarray['item_hidden'] = $item_hidden;
    $datarray['item_unpublished'] = $item_unpublished;
    $datarray['item_delayed'] = $item_delayed;
    $datarray['item_pending_remove'] = $item_pending_remove;
    $datarray['item_blocked'] = $item_blocked;
    $datarray['layout_mid'] = $layout_mid;
    $datarray['public_policy'] = $public_policy;
    $datarray['comment_policy'] = map_scope($channel['channel_w_comment']);
    $datarray['term'] = $post_tags;
    $datarray['plink'] = $plink;
    $datarray['route'] = $route;
    if ($iconfig) {
        $datarray['iconfig'] = $iconfig;
    }
    // preview mode - prepare the body for display and send it via json
    if ($preview) {
        require_once 'include/conversation.php';
        $datarray['owner'] = $owner_xchan;
        $datarray['author'] = $observer;
        $datarray['attach'] = json_encode($datarray['attach']);
        $o = conversation($a, array($datarray), 'search', false, 'preview');
        //		logger('preview: ' . $o, LOGGER_DEBUG);
        echo json_encode(array('preview' => $o));
        killme();
    }
    if ($orig_post) {
        $datarray['edit'] = true;
    }
    if (feature_enabled($profile_uid, 'suppress_duplicates') && !$orig_post) {
        $z = q("select created from item where uid = %d and body = '%s'", intval($profile_uid), dbesc($body));
        if ($z) {
            foreach ($z as $zz) {
                if ($zz['created'] > datetime_convert('UTC', 'UTC', 'now - 2 minutes')) {
                    $datarray['cancel'] = 1;
                    notice(t('Duplicate post suppressed.') . EOL);
                    logger('Duplicate post. Faking plugin cancel.');
                }
            }
        }
    }
    call_hooks('post_local', $datarray);
    if (x($datarray, 'cancel')) {
        logger('mod_item: post cancelled by plugin or duplicate suppressed.');
        if ($return_path) {
            goaway(z_root() . "/" . $return_path);
        }
        $json = array('cancel' => 1);
        $json['reload'] = z_root() . '/' . $_REQUEST['jsreload'];
        echo json_encode($json);
        killme();
    }
    if (mb_strlen($datarray['title']) > 255) {
        $datarray['title'] = mb_substr($datarray['title'], 0, 255);
    }
    if (array_key_exists('item_private', $datarray) && $datarray['item_private']) {
        $datarray['body'] = trim(z_input_filter($datarray['uid'], $datarray['body'], $datarray['mimetype']));
        if ($uid) {
            if ($channel['channel_hash'] === $datarray['author_xchan']) {
                $datarray['sig'] = base64url_encode(rsa_sign($datarray['body'], $channel['channel_prvkey']));
                $datarray['item_verified'] = 1;
            }
        }
    }
    if ($orig_post) {
        $datarray['id'] = $post_id;
        item_store_update($datarray, $execflag);
        update_remote_id($channel, $post_id, $webpage, $pagetitle, $namespace, $remote_id, $mid);
        if (!$parent) {
            $r = q("select * from item where id = %d", intval($post_id));
            if ($r) {
                xchan_query($r);
                $sync_item = fetch_post_tags($r);
                $rid = q("select * from item_id where iid = %d", intval($post_id));
                build_sync_packet($uid, array('item' => array(encode_item($sync_item[0], true)), 'item_id' => $rid));
            }
        }
        if (!$nopush) {
            proc_run('php', "include/notifier.php", 'edit_post', $post_id);
        }
        if (x($_REQUEST, 'return') && strlen($return_path)) {
            logger('return: ' . $return_path);
            goaway(z_root() . "/" . $return_path);
        }
        killme();
    } else {
        $post_id = 0;
    }
    $post = item_store($datarray, $execflag);
    $post_id = $post['item_id'];
    if ($post_id) {
        logger('mod_item: saved item ' . $post_id);
        if ($parent) {
            // only send comment notification if this is a wall-to-wall comment,
            // otherwise it will happen during delivery
            if ($datarray['owner_xchan'] != $datarray['author_xchan'] && intval($parent_item['item_wall'])) {
                notification(array('type' => NOTIFY_COMMENT, 'from_xchan' => $datarray['author_xchan'], 'to_xchan' => $datarray['owner_xchan'], 'item' => $datarray, 'link' => z_root() . '/display/' . $datarray['mid'], 'verb' => ACTIVITY_POST, 'otype' => 'item', 'parent' => $parent, 'parent_mid' => $parent_item['mid']));
            }
        } else {
            $parent = $post_id;
            if ($datarray['owner_xchan'] != $datarray['author_xchan'] && $datarray['item_type'] == ITEM_TYPE_POST) {
                notification(array('type' => NOTIFY_WALL, 'from_xchan' => $datarray['author_xchan'], 'to_xchan' => $datarray['owner_xchan'], 'item' => $datarray, 'link' => z_root() . '/display/' . $datarray['mid'], 'verb' => ACTIVITY_POST, 'otype' => 'item'));
            }
            if ($uid && $uid == $profile_uid && is_item_normal($datarray)) {
                q("update channel set channel_lastpost = '%s' where channel_id = %d", dbesc(datetime_convert()), intval($uid));
            }
        }
        // photo comments turn the corresponding item visible to the profile wall
        // This way we don't see every picture in your new photo album posted to your wall at once.
        // They will show up as people comment on them.
        if (intval($parent_item['item_hidden'])) {
            $r = q("UPDATE item SET item_hidden = 0 WHERE id = %d", intval($parent_item['id']));
        }
    } else {
        logger('mod_item: unable to retrieve post that was just stored.');
        notice(t('System error. Post not saved.') . EOL);
        goaway(z_root() . "/" . $return_path);
        // NOTREACHED
    }
    update_remote_id($channel, $post_id, $webpage, $pagetitle, $namespace, $remote_id, $mid);
    if ($parent && $parent != $post_id) {
        // Store the comment signature information in case we need to relay to Diaspora
        $ditem = $datarray;
        $ditem['author'] = $observer;
        store_diaspora_comment_sig($ditem, $channel, $parent_item, $post_id, $walltowall_comment ? 1 : 0);
    } else {
        $r = q("select * from item where id = %d", intval($post_id));
        if ($r) {
            xchan_query($r);
            $sync_item = fetch_post_tags($r);
            $rid = q("select * from item_id where iid = %d", intval($post_id));
            build_sync_packet($uid, array('item' => array(encode_item($sync_item[0], true)), 'item_id' => $rid));
        }
    }
    $datarray['id'] = $post_id;
    $datarray['llink'] = z_root() . '/display/' . $channel['channel_address'] . '/' . $post_id;
    call_hooks('post_local_end', $datarray);
    if (!$nopush) {
        proc_run('php', 'include/notifier.php', $notify_type, $post_id);
    }
    logger('post_complete');
    // figure out how to return, depending on from whence we came
    if ($api_source) {
        return $post;
    }
    if ($return_path) {
        goaway(z_root() . "/" . $return_path);
    }
    $json = array('success' => 1);
    if (x($_REQUEST, 'jsreload') && strlen($_REQUEST['jsreload'])) {
        $json['reload'] = z_root() . '/' . $_REQUEST['jsreload'];
    }
    logger('post_json: ' . print_r($json, true), LOGGER_DEBUG);
    echo json_encode($json);
    killme();
    // NOTREACHED
}
Beispiel #12
0
 function post()
 {
     require_once 'include/wiki.php';
     // /wiki/channel/preview
     // Render mardown-formatted text in HTML for preview
     if (argc() > 2 && argv(2) === 'preview') {
         $content = $_POST['content'];
         $resource_id = $_POST['resource_id'];
         require_once 'library/markdown.php';
         $html = wiki_generate_toc(purify_html(Markdown($content)));
         $w = wiki_get_wiki($resource_id);
         $wikiURL = argv(0) . '/' . argv(1) . '/' . $w['urlName'];
         $html = wiki_convert_links($html, $wikiURL);
         json_return_and_die(array('html' => $html, 'success' => true));
     }
     // Create a new wiki
     // /wiki/channel/create/wiki
     if (argc() > 3 && argv(2) === 'create' && argv(3) === 'wiki') {
         $nick = argv(1);
         $channel = get_channel_by_nick($nick);
         // Determine if observer has permission to create wiki
         $observer_hash = get_observer_hash();
         // Only the channel owner can create a wiki, at least until we create a
         // more detail permissions framework
         if (local_channel() !== intval($channel['channel_id'])) {
             goaway('/' . argv(0) . '/' . $nick . '/');
         }
         $wiki = array();
         // Generate new wiki info from input name
         $wiki['postVisible'] = intval($_POST['postVisible']) === 0 ? 0 : 1;
         $wiki['rawName'] = $_POST['wikiName'];
         $wiki['htmlName'] = escape_tags($_POST['wikiName']);
         $wiki['urlName'] = urlencode($_POST['wikiName']);
         if ($wiki['urlName'] === '') {
             notice('Error creating wiki. Invalid name.');
             goaway('/wiki');
         }
         // Get ACL for permissions
         $acl = new \Zotlabs\Access\AccessList($channel);
         $acl->set_from_array($_POST);
         $r = wiki_create_wiki($channel, $observer_hash, $wiki, $acl);
         if ($r['success']) {
             $homePage = wiki_create_page('Home', $r['item']['resource_id']);
             if (!$homePage['success']) {
                 notice('Wiki created, but error creating Home page.');
                 goaway('/wiki/' . $nick . '/' . $wiki['urlName']);
             }
             goaway('/wiki/' . $nick . '/' . $wiki['urlName'] . '/' . $homePage['page']['urlName']);
         } else {
             notice('Error creating wiki');
             goaway('/wiki');
         }
     }
     // Delete a wiki
     if (argc() > 3 && argv(2) === 'delete' && argv(3) === 'wiki') {
         $nick = argv(1);
         $channel = get_channel_by_nick($nick);
         // Only the channel owner can delete a wiki, at least until we create a
         // more detail permissions framework
         if (local_channel() !== intval($channel['channel_id'])) {
             logger('Wiki delete permission denied.' . EOL);
             json_return_and_die(array('message' => 'Wiki delete permission denied.', 'success' => false));
         }
         $resource_id = $_POST['resource_id'];
         $deleted = wiki_delete_wiki($resource_id);
         if ($deleted['success']) {
             json_return_and_die(array('message' => '', 'success' => true));
         } else {
             logger('Error deleting wiki: ' . $resource_id);
             json_return_and_die(array('message' => 'Error deleting wiki', 'success' => false));
         }
     }
     // Create a page
     if (argc() === 4 && argv(2) === 'create' && argv(3) === 'page') {
         $nick = argv(1);
         $resource_id = $_POST['resource_id'];
         // Determine if observer has permission to create a page
         $channel = get_channel_by_nick($nick);
         if (local_channel() !== intval($channel['channel_id'])) {
             $observer_hash = get_observer_hash();
             $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
             if (!$perms['write']) {
                 logger('Wiki write permission denied. ' . EOL);
                 json_return_and_die(array('success' => false));
             }
         }
         $name = $_POST['name'];
         //Get new page name
         if (urlencode(escape_tags($_POST['name'])) === '') {
             json_return_and_die(array('message' => 'Error creating page. Invalid name.', 'success' => false));
         }
         $page = wiki_create_page($name, $resource_id);
         if ($page['success']) {
             json_return_and_die(array('url' => '/' . argv(0) . '/' . argv(1) . '/' . $page['wiki']['urlName'] . '/' . urlencode($page['page']['urlName']), 'success' => true));
         } else {
             logger('Error creating page');
             json_return_and_die(array('message' => 'Error creating page.', 'success' => false));
         }
     }
     // Fetch page list for a wiki
     if (argc() === 5 && argv(2) === 'get' && argv(3) === 'page' && argv(4) === 'list') {
         $resource_id = $_POST['resource_id'];
         // resource_id for wiki in db
         $channel = get_channel_by_nick(argv(1));
         $observer_hash = get_observer_hash();
         if (local_channel() !== intval($channel['channel_id'])) {
             $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
             if (!$perms['read']) {
                 logger('Wiki read permission denied.' . EOL);
                 json_return_and_die(array('pages' => null, 'message' => 'Permission denied.', 'success' => false));
             }
         }
         $page_list_html = widget_wiki_pages(array('resource_id' => $resource_id, 'refresh' => true, 'channel' => argv(1)));
         json_return_and_die(array('pages' => $page_list_html, 'message' => '', 'success' => true));
     }
     // Save a page
     if (argc() === 4 && argv(2) === 'save' && argv(3) === 'page') {
         $resource_id = $_POST['resource_id'];
         $pageUrlName = $_POST['name'];
         $pageHtmlName = escape_tags($_POST['name']);
         $content = $_POST['content'];
         //Get new content
         $commitMsg = $_POST['commitMsg'];
         if ($commitMsg === '') {
             $commitMsg = 'Updated ' . $pageHtmlName;
         }
         $nick = argv(1);
         $channel = get_channel_by_nick($nick);
         // Determine if observer has permission to save content
         if (local_channel() !== intval($channel['channel_id'])) {
             $observer_hash = get_observer_hash();
             $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
             if (!$perms['write']) {
                 logger('Wiki write permission denied. ' . EOL);
                 json_return_and_die(array('success' => false));
             }
         }
         $saved = wiki_save_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'content' => $content));
         if ($saved['success']) {
             $ob = \App::get_observer();
             $commit = wiki_git_commit(array('commit_msg' => $commitMsg, 'resource_id' => $resource_id, 'observer' => $ob, 'files' => array($pageUrlName . '.md')));
             if ($commit['success']) {
                 json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true));
             } else {
                 json_return_and_die(array('message' => 'Error making git commit', 'success' => false));
             }
         } else {
             json_return_and_die(array('message' => 'Error saving page', 'success' => false));
         }
     }
     // Update page history
     // /wiki/channel/history/page
     if (argc() === 4 && argv(2) === 'history' && argv(3) === 'page') {
         $resource_id = $_POST['resource_id'];
         $pageUrlName = $_POST['name'];
         $nick = argv(1);
         $channel = get_channel_by_nick($nick);
         // Determine if observer has permission to read content
         if (local_channel() !== intval($channel['channel_id'])) {
             $observer_hash = get_observer_hash();
             $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
             if (!$perms['read']) {
                 logger('Wiki read permission denied.' . EOL);
                 json_return_and_die(array('historyHTML' => '', 'message' => 'Permission denied.', 'success' => false));
             }
         }
         $historyHTML = widget_wiki_page_history(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
         json_return_and_die(array('historyHTML' => $historyHTML, 'message' => '', 'success' => true));
     }
     // Delete a page
     if (argc() === 4 && argv(2) === 'delete' && argv(3) === 'page') {
         $resource_id = $_POST['resource_id'];
         $pageUrlName = $_POST['name'];
         if ($pageUrlName === 'Home') {
             json_return_and_die(array('message' => 'Cannot delete Home', 'success' => false));
         }
         // Determine if observer has permission to delete pages
         $nick = argv(1);
         $channel = get_channel_by_nick($nick);
         if (local_channel() !== intval($channel['channel_id'])) {
             $observer_hash = get_observer_hash();
             $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
             if (!$perms['write']) {
                 logger('Wiki write permission denied. ' . EOL);
                 json_return_and_die(array('success' => false));
             }
         }
         $deleted = wiki_delete_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
         if ($deleted['success']) {
             $ob = \App::get_observer();
             $commit = wiki_git_commit(array('commit_msg' => 'Deleted ' . $pageUrlName, 'resource_id' => $resource_id, 'observer' => $ob, 'files' => null));
             if ($commit['success']) {
                 json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true));
             } else {
                 json_return_and_die(array('message' => 'Error making git commit', 'success' => false));
             }
         } else {
             json_return_and_die(array('message' => 'Error deleting page', 'success' => false));
         }
     }
     // Revert a page
     if (argc() === 4 && argv(2) === 'revert' && argv(3) === 'page') {
         $resource_id = $_POST['resource_id'];
         $pageUrlName = $_POST['name'];
         $commitHash = $_POST['commitHash'];
         // Determine if observer has permission to revert pages
         $nick = argv(1);
         $channel = get_channel_by_nick($nick);
         if (local_channel() !== intval($channel['channel_id'])) {
             $observer_hash = get_observer_hash();
             $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
             if (!$perms['write']) {
                 logger('Wiki write permission denied.' . EOL);
                 json_return_and_die(array('success' => false));
             }
         }
         $reverted = wiki_revert_page(array('commitHash' => $commitHash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
         if ($reverted['success']) {
             json_return_and_die(array('content' => $reverted['content'], 'message' => '', 'success' => true));
         } else {
             json_return_and_die(array('content' => '', 'message' => 'Error reverting page', 'success' => false));
         }
     }
     // Compare page revisions
     if (argc() === 4 && argv(2) === 'compare' && argv(3) === 'page') {
         $resource_id = $_POST['resource_id'];
         $pageUrlName = $_POST['name'];
         $compareCommit = $_POST['compareCommit'];
         $currentCommit = $_POST['currentCommit'];
         // Determine if observer has permission to revert pages
         $nick = argv(1);
         $channel = get_channel_by_nick($nick);
         if (local_channel() !== intval($channel['channel_id'])) {
             $observer_hash = get_observer_hash();
             $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
             if (!$perms['read']) {
                 logger('Wiki read permission denied.' . EOL);
                 json_return_and_die(array('success' => false));
             }
         }
         $compare = wiki_compare_page(array('currentCommit' => $currentCommit, 'compareCommit' => $compareCommit, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
         if ($compare['success']) {
             $diffHTML = '<table class="text-center" width="100%"><tr><td class="lead" width="50%">Current Revision</td><td class="lead" width="50%">Selected Revision</td></tr></table>' . $compare['diff'];
             json_return_and_die(array('diff' => $diffHTML, 'message' => '', 'success' => true));
         } else {
             json_return_and_die(array('diff' => '', 'message' => 'Error comparing page', 'success' => false));
         }
     }
     // Rename a page
     if (argc() === 4 && argv(2) === 'rename' && argv(3) === 'page') {
         $resource_id = $_POST['resource_id'];
         $pageUrlName = $_POST['oldName'];
         $pageNewName = $_POST['newName'];
         if ($pageUrlName === 'Home') {
             json_return_and_die(array('message' => 'Cannot rename Home', 'success' => false));
         }
         if (urlencode(escape_tags($pageNewName)) === '') {
             json_return_and_die(array('message' => 'Error renaming page. Invalid name.', 'success' => false));
         }
         // Determine if observer has permission to rename pages
         $nick = argv(1);
         $channel = get_channel_by_nick($nick);
         if (local_channel() !== intval($channel['channel_id'])) {
             $observer_hash = get_observer_hash();
             $perms = wiki_get_permissions($resource_id, intval($channel['channel_id']), $observer_hash);
             if (!$perms['write']) {
                 logger('Wiki write permission denied. ' . EOL);
                 json_return_and_die(array('success' => false));
             }
         }
         $renamed = wiki_rename_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'pageNewName' => $pageNewName));
         if ($renamed['success']) {
             $ob = \App::get_observer();
             $commit = wiki_git_commit(array('commit_msg' => 'Renamed ' . urldecode($pageUrlName) . ' to ' . $renamed['page']['htmlName'], 'resource_id' => $resource_id, 'observer' => $ob, 'files' => array($pageUrlName . '.md', $renamed['page']['fileName']), 'all' => true));
             if ($commit['success']) {
                 json_return_and_die(array('name' => $renamed['page'], 'message' => 'Wiki git repo commit made', 'success' => true));
             } else {
                 json_return_and_die(array('message' => 'Error making git commit', 'success' => false));
             }
         } else {
             json_return_and_die(array('message' => 'Error renaming page', 'success' => false));
         }
     }
     //notice('You must be authenticated.');
     json_return_and_die(array('message' => 'You must be authenticated.', 'success' => false));
 }