Changeset 894

Show
Ignore:
Timestamp:
02/25/08 18:54:14
Author:
goldoraf
Message:

Major improvements of notifier demo app

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • apps/notifier/app/models/user.php

    r882 r894  
    44{ 
    55    public static $objects; 
     6    public static $relationships = array( 
     7        'friends' => array('assoc_type' => 'many_to_many', 'join_table' => 'friendships', 
     8                           'class_name' => 'User')   
     9    ); 
    610     
    711    public static function authenticate($login, $password) 
    812    { 
    913        try { 
    10             return User::$objects->get('name = ?', array($login, md5($password))); 
     14            return User::$objects->get('name = ?', 'pwd = ?', array($login, md5($password))); 
    1115        } catch (SRecordNotFound $e) { 
    1216            return false; 
     
    2024        $this->validate_uniqueness_of('name', array('message' => 'est déjà pris')); 
    2125    } 
     26     
     27    public function serializable_form() 
     28    { 
     29        return parent::serializable_form(array('exclude' => array('pwd'))); 
     30    } 
    2231} 
    2332 
  • apps/notifier/app/resources/base_resource.php

    r882 r894  
    66{ 
    77    protected $authenticated_user; 
    8      
    9     protected $before_filters = array('authenticate'); 
     8    protected $user; 
    109     
    1110    protected function authenticate() 
     
    1615    } 
    1716     
    18     protected function must_specifiy_user() 
     17    protected function must_specify_user() 
    1918    { 
    20         $this->user = User::$objects->get_by_name($this->params['username']); 
     19        try { 
     20            $this->user = User::$objects->get_by_name($this->params['username']); 
     21        } catch (SRecordNotFound $e) { 
     22            return false; 
     23        } 
    2124    } 
    2225     
  • apps/notifier/app/resources/users_resource.php

    r884 r894  
    33class UsersResource extends BaseResource 
    44{ 
    5     protected $before_filters = array(array('authenticate', 'except' => 'post')); 
     5    public function __construct() 
     6    { 
     7        $this->add_before_filter('authenticate', array('except' => 'post')); 
     8    } 
    69     
    710    public function post() 
    811    { 
    9         $user = new User($this->params['user']); 
    10         if ($user->save()) 
    11             $this->responds_created($user); 
    12         else 
    13             $this->responds_error($user->errors, 400); 
     12        try { 
     13            $user = User::$objects->get_by_name($this->params['user']['name']); 
     14            // le nom d'utilisateur est déjà pris 
     15            $this->responds_error(409); 
     16        } catch (SRecordNotFound $e) { 
     17            $this->params['user']['pwd'] = md5($this->params['user']['pwd']); 
     18            $user = new User($this->params['user']); 
     19            if ($user->save()) 
     20                $this->responds_nothing(201); 
     21            else 
     22                $this->responds_detailed_error($user->errors, 400); 
     23        } 
    1424    } 
    1525} 
  • apps/notifier/app/views/test/index.php

    r884 r894  
    1313    <div id="login"> 
    1414        <label for="login">Identifiant</label> 
    15         <input type="text" id="login" value="" /> 
     15        <input type="text" id="name" value="" /> 
    1616        <label for="pwd">Mot de passe</label> 
    1717        <input type="password" id="pwd" value="" /> 
     
    2323        <input type="text" id="reg_email" value="" /> 
    2424        <label for="reg_login">Identifiant</label> 
    25         <input type="text" id="reg_login" value="" /> 
     25        <input type="text" id="reg_name" value="" /> 
    2626        <label for="reg_pwd">Mot de passe</label> 
    2727        <input type="password" id="reg_pwd" value="" /> 
     
    3131        <div id="tabs"> 
    3232            <a href="#" class="active" onclick="notifier.ui.showTab(this, 'friends-timeline');">Timeline</a> 
    33             <a href="#" onclick="notifier.ui.showTab(this, 'friends');">Friends</a> 
     33            <a href="#" onclick="notifier.ui.showTab(this, 'friends');notifier.actions.refreshFriendsList();">Friends</a> 
    3434            <a href="#" onclick="notifier.ui.showTab(this, 'favorites');">Favorites</a>  
    3535        </div> 
     
    3737            <h2>Timeline</h2> 
    3838            <textarea rows="8" id="note_text"></textarea> 
    39             <input type="submit" onclick="notifier.api.sendNote($('#note_text').val(), notifier.ui.prependNote);"  
    40                                  value="Envoyer" /> 
     39            <input type="submit" id="note_submit" onclick="notifier.actions.sendNote();" value="Envoyer" /> 
    4140            <a href="#" onclick="notifier.actions.refreshFriendsTimeline();">Actualiser</a> 
    4241            <div id="friends-timeline"></div> 
     
    4443        <div id="friends-tab" class="tab" style="display:none;"> 
    4544            <h2>Friends</h2> 
     45            <div id="friends-list"></div> 
    4646        </div> 
    4747        <div id="favorites-tab" class="tab" style="display:none;"> 
  • apps/notifier/conf/routes.php

    r882 r894  
    22 
    33$map = new SRouteSet(); 
    4 $map->connect('api/notes/:id', array('resource' => 'notes')); 
    5 $map->connect('api/public_timeline', array('resource' => 'public_timeline')); 
    6 $map->connect('api/users', array('resource' => 'users')); 
     4$map->connect('api/users/:username/statuses/:id', array('resource' => 'statuses')); 
     5$map->connect('api/users/:username/timeline', array('resource' => 'user_timeline')); 
     6$map->connect('api/users/:username/friends/timeline', array('resource' => 'friends_timeline')); 
     7$map->connect('api/users/:username/friends', array('resource' => 'friends')); 
     8$map->connect('api/users/:id', array('resource' => 'users')); 
     9 
    710$map->connect(':controller/:action/:id'); 
    811 
  • apps/notifier/db/db_schema.php

    r844 r894  
    33return array 
    44( 
    5     new STable('notes', array( 
     5    new STable('statuses', array( 
    66        new SColumn('id', SColumn::PK), 
    77        new SColumn('text', SColumn::TEXT), 
     
    1515        new SColumn('pwd', SColumn::STRING) 
    1616    )), 
     17    new STable('friendships', array( 
     18        new SColumn('user_id', SColumn::INTEGER), 
     19        new SColumn('friend_id', SColumn::INTEGER) 
     20    )) 
    1721); 
    1822 
  • apps/notifier/public/js/notifier.js

    r884 r894  
    33notifier.prefs = {}; 
    44notifier.prefs.baseUrl = 'http://localhost/notifier/api/'; 
    5 notifier.prefs.username = 'test@test.com'; 
    6 notifier.prefs.password = 'test'; 
     5notifier.prefs.username = ''; 
     6notifier.prefs.password = ''; 
    77 
    88notifier.actions = {}; 
    99notifier.actions.login = function() { 
    10         $('#login').hide(); 
     10        notifier.prefs.username = $('#name').val(); 
     11    notifier.prefs.password = $('#pwd').val(); 
     12    $('#login').hide(); 
    1113    $('#main').show(); 
     14    notifier.actions.refreshFriendsTimeline(); 
    1215} 
    1316notifier.actions.register = function() { 
    1417    var data = { 
    15         'user[name]': $('#reg_login').val(), 
     18        'user[name]': $('#reg_name').val(), 
    1619        'user[email]': $('#reg_email').val(), 
    1720        'user[pwd]': $('#reg_pwd').val() 
     
    1922    notifier.api.doRequest('users.json', { 
    2023        method: 'POST', 
     24        authenticate: false, 
    2125        params: data, 
    2226        success: function() { 
    2327            $('#register').hide(); 
    2428            $('#login').show(); 
     29        }, 
     30        error: function(error, status) { 
     31            if (status == 409) { 
     32                alert("Ce nom d'utilisateur est déjà pris !"); 
     33            } else { 
     34                notifier.api.alertError(error, status); 
     35            } 
    2536        } 
    2637    }); 
    2738} 
    2839notifier.actions.refreshFriendsTimeline = function() { 
     40    notifier.api.doRequest('users/'+notifier.prefs.username+'/friends/timeline.json', { 
     41        success: function(notes) { 
     42            $('#friends-timeline').empty(); 
     43            for (var i in notes) { 
     44                $('#friends-timeline').append(notifier.ui.htmlForNote(notes[i])); 
     45            } 
     46        } 
     47    }); 
     48} 
     49notifier.actions.sendNote = function() { 
     50    text = $('#note_text').val(); 
     51    $('#note_submit').attr('disabled', 'true'); 
     52    notifier.api.doRequest('users/'+notifier.prefs.username+'/statuses.json', { 
     53        method: 'POST', 
     54        params: {'text': text}, 
     55        success: function(note) { 
     56            notifier.ui.prependNote(note); 
     57            $('#note_text').val(''); 
     58            $('#note_submit').attr('disabled', 'false'); 
     59        }, 
     60        error: function(error, status) { 
     61            $('#note_submit').attr('disabled', 'false'); 
     62            notifier.api.alertError(error, status); 
     63        } 
     64    }); 
     65} 
     66notifier.actions.deleteNote = function(noteId) { 
     67    if (!confirm('Etes-vous sûr de vouloir supprimer cette note ?')) return; 
    2968     
     69    notifier.api.doRequest('users/'+notifier.prefs.username+'/statuses/'+noteId+'.json', { 
     70        method: 'DELETE', 
     71        success: function() { 
     72            $('#note_'+noteId).remove(); 
     73        } 
     74    }); 
     75} 
     76notifier.actions.refreshFriendsList = function() { 
     77    notifier.api.doRequest('users/'+notifier.prefs.username+'/friends.json', { 
     78        success: function(friends) { 
     79            $('#friends-list').empty(); 
     80            for (var i in friends) { 
     81                $('#friends-list').append(notifier.ui.htmlForFriend(friends[i])); 
     82            } 
     83        } 
     84    }); 
    3085} 
    3186 
     
    4196} 
    4297notifier.ui.htmlForNote = function(note) { 
    43     return '<div class="note">' 
    44             +'<p class="note-text">'+note.text+'</p>' 
    45             +'<p class="note-details">'+'raphael'+' le '+note.timestamp+'</p>' 
    46             +'</div>' 
    47 
    48 notifier.ui.refreshFriendsTimeline = function(notes) { 
    49     $('#friends-timeline').empty(); 
    50     for (var i in notes) { 
    51         $('#friends-timeline').append(notifier.ui.htmlForNote(notes[i])); 
     98    var html = '<div class="note" id="note_'+note.id+'">' 
     99             +'<p class="note-text">'+note.text+'</p>' 
     100             +'<p class="note-details">'+note.sender.name+' le '+note.timestamp 
     101    if (note.sender.name == notifier.prefs.username) { 
     102        html+= '&nbsp;<a href="#" onclick="notifier.actions.deleteNote(\''+note.id+'\');">delete</a>'; 
    52103    } 
     104    html+= '</p></div>'; 
     105    return html; 
    53106} 
    54107notifier.ui.prependNote = function(note) { 
    55108    $('#friends-timeline').prepend(notifier.ui.htmlForNote(note)); 
     109} 
     110notifier.ui.htmlForFriend = function(friend) { 
     111    return '<div class="friend">' 
     112            +'<span class="friend-avatar">?</span>' 
     113            +'<p class="friend-name">'+friend.name+'</p>' 
     114            +'<p class="friend-email">'+friend.email+'</p>' 
     115            +'</div>' 
    56116} 
    57117 
     
    61121        method: 'GET', 
    62122        params: {}, 
    63         authenticate: false, 
     123        authenticate: true, 
    64124        success: null, 
    65125        error: null 
     
    78138            if (options.authenticate) { 
    79139                xhr.setRequestHeader("Authorization",  
    80                     "Basic " + Base64.encode(notifier.prefs.email + ":" + notifier.prefs.password)); 
     140                    "Basic " + Base64.encode(notifier.prefs.username + ":" + notifier.prefs.password)); 
    81141                xhr.setRequestHeader("Cookie", ""); 
    82142            } 
     
    103163            } 
    104164            if (options.error !== null) { 
    105                 options.error(data, status); 
     165                options.error(error, xhr.status); 
    106166            } else { 
    107                 var str = "Erreur "+xhr.status+" !\n\n"; 
    108                 for (var key in error) { 
    109                     str += key+': '+error[key]+"\n"; 
    110                 } 
    111                 alert(str); 
     167                notifier.api.alertError(error, xhr.status); 
    112168            } 
    113169        } 
     
    115171    return $.ajax(reqParams);            
    116172} 
    117  
    118 notifier.api.sendNote = function(text) { 
    119     return this.doRequest('notes.json', { 
    120         method: 'POST', 
    121         params: {'text': text}, 
    122         callback: callback 
    123     }); 
     173notifier.api.alertError = function(error, status) { 
     174    var str = "Erreur "+status+" !\n\n"; 
     175    for (var key in error) { 
     176        str += key+': '+error[key]+"\n"; 
     177    } 
     178    alert(str); 
    124179} 
    125180 
    126 notifier.api.publicTimeline = function(callback) { 
    127     return this.doRequest('public_timeline.json', { 
    128         callback: callback 
    129     }); 
    130 
     181 
  • apps/notifier/public/styles/main.css

    r882 r894  
    5050} 
    5151     
    52 div.note
     52div.note, div.friend
    5353        border-top: 1px solid #ccc; 
    5454} 
     
    6565        color: #bbb; 
    6666} 
     67span.friend-avatar { 
     68    font-size: 24px; 
     69    font-weight: bold; 
     70    float: left; 
     71    border: 1px solid black; 
     72        background-color: #e6f2fe; 
     73        margin: 5px 10px 0 0; 
     74    padding: 5px 10px; 
     75    text-align: center; 
     76} 
     77p.friend-name { 
     78    font-size: 16px; 
     79    padding: 5px; 
     80} 
     81p.friend-email { 
     82    font-size: 11px; 
     83    color: #bbb; 
     84}