1
<?php
2
#TODO: implement search filter (e.g. 'contains the words', for microblogs)
3
#TODO: implement weighting, so that high-volume feeds (libre.fm, delicious) don't
4
#        drown out important things like blog posts and videos
5
#TODO: store table names as variables
6
#TODO: XSLT output (can this handle inheritance? A little formatting still needed, I think)
7
#TODO: multiple links -- combine timeSince if they're all the same...
8
#TODO: it'd be cool to combine Delicious, Google Reader and StumbleUpon stories...
9
#			and Facebook Posted Items... because sometimes that happens for the same link
10
#TODO: need to query for more if not enough retrieved (LIMIT estimated)
11
12
//function __autoload($class_name){
13
//	require_once 'modules/' . strtolower($class_name) . '.class.php';
14
//}
15
require('entry.class.php');
16
require('settings.php');
17
require('modules.php');
18
19
define('ABS_PATH', dirname(__FILE__));
20
define('DEFAULT_ENTRY_ICON', '/default_icon.png');
21
22
/**
23
 * Load db settings and connect.
24
 * @return database handling
25
 */
26
function db_connect() {
27
  $dbh = @mysql_connect(DB_HOST, DB_USER, DB_PASS);
28
  if(!$dbh)
29
  	die('Could not connect: ' . mysql_error());
30
  if(!mysql_select_db(DB_NAME, $dbh))
31
  	die('Could not select database: ' . mysql_error());
32
  	
33
 return $dbh;
34
}
35
36
/**
37
 * Load entries from the database, return as array.
38
 * @param $dbh -- database link identifier
39
 * @param $filter_query -- WHERE clauses, if any
40
 * @param $max -- number of desired entries to load.
41
 * @param $more -- used as a pager so that, if this function is called multiple
42
 *                times with other parameters constant but $more increment, it
43
 *                will return the next entries from the same query...
44
 */
45
function load_entries($dbh, $filter_query, $limit, $more = 0) {
46
  $limit = (int)($limit);
47
  $entries = array();
48
  
49
  // Load entries  
50
  $sql = "SELECT e.*, f.type as feed_type, f.title as feed_title, f.link as feed_link, f.id as feed_id FROM entries e 
51
            LEFT OUTER JOIN feeds f ON f.id=e.feed_id 
52
            $filter_query
53
            ORDER BY e.rec_updated DESC
54
            LIMIT ".$more*$limit .', '. $limit;
55
  
56
  $result = mysql_query($sql, $dbh);
57
  if(!$result)
58
  	die('Query failed: ' . mysql_error($dbh));
59
60
  while ($row = mysql_fetch_assoc($result)) {
61
    $class = class_exists($row['feed_type']) ? $row['feed_type'] : 'Entry';
62
  	$entries[] = new $class($row);
63
  }
64
  
65
  // TODO: look for a more elegant way to express this
66
  
67
  // Join any duplicate entries
68
  for($i = 0; $i < count($entries); $i++){
69
  	while(is_callable(array($entries[$i], 'equals')) and
70
  		$i+1 < count($entries) and
71
  		is_callable(array($entries[$i+1], 'equals')) and
72
  		$entries[$i]->equals($entries[$i+1])){
73
74
  		$entries[$i]->merge($entries[$i+1]);
75
  		if($i+2 < count($entries))
76
  			$entries = array_merge(
77
  				array_slice($entries, 0, $i+1),
78
  				array_slice($entries, $i+2));
79
  		else
80
  			$entries = array_slice($entries, 0, $i+1);
81
    }
82
  }
83
  
84
  return $entries;
85
}
86
87
/**
88
 * Return an unordered list of the entries from the database
89
 * which match the following criteria.
90
 */
91
function get_entries($filters = array(), $max = 20, $with_like = array()) {
92
  $dbh = db_connect();
93
  
94
  // Build query filters
95
  $filter_query = "";
96
  if ($filters) {
97
    $fields = array('tag' => 't.name', 'feed' => 'f.id');
98
99
    // Load filters
100
    foreach ($filters as $key => $value) {
101
      if ($value) {
102
        $key = $fields[$key];
103
        
104
        // If string, add check for this single value
105
        if (!is_array($value)) {
106
          $value = mysql_real_escape_string($value);
107
          $this_filter_query = "$key='$value'";
108
        }
109
110
        // If array, match any of the values
111
        else {
112
          $this_filter_query = '';
113
          foreach ($value as $this_value) {
114
            $this_value = mysql_real_escape_string($this_value);
115
            $this_filter_query .= ($this_filter_query ? ' OR ' : '') ."$key='$this_value'";
116
          }
117
        }
118
        $filter_query .= (!$filter_query ? ' WHERE ' : ' AND ') ."($this_filter_query)";
119
      }
120
   
121
      if ($with_like) {
122
        $filter_query .= " OR e.title LIKE '%$with_like%' ";
123
      }
124
      // If filtering by tag, join tag tables
125
      if (isset($filters['tag']) && $filters['tag']) {
126
        $filter_query = 'LEFT OUTER JOIN tag_relationships x ON e.id=x.entry_id
127
                         LEFT OUTER JOIN tags t ON x.tag_id=t.id '. $filter_query;
128
      }
129
    }
130
  }
131
  
132
133
  $entries = load_entries($dbh, $filter_query, $max*2);
134
  if (!$entries) {
135
    return '<p>No activity.</p>'; //nothing to show
136
  }
137
  $more = 0; //used later if we need to load more
138
139
  $ul = "\n<ul>";
140
141
  // Add entries to list
142
  for($i = 0; $i < count($entries); $i++){
143
  	// Get more entries if we're on the last one
144
  	if ($i == count($entries)-1) {
145
  	  $more++;
146
      $entries = array_merge($entries, load_entries($dbh, $filter_query, $max*2, $more));
147
  	}
148
149
  
150
  
151
  	$entry = $entries[$i];
152
  	
153
  	// Check for a series of events
154
  	$multiple = array();
155
  	if($entry->canHaveMultiples()) {
156
  		while($i+1 < count($entries) && $entry->groupTogether($entries[$i+1])){
157
  			$multiple[] = $entries[$i+1];
158
  			
159
  			$i++;
160
161
      	// Get more entries if we're on the last one TODO: this will never stop if whole query is multiples
162
      	if ($i == count($entries)-1) {
163
      	  $more++;
164
          $entries = array_merge($entries, load_entries($dbh, $filter_query, $max*2, $more));
165
      	}
166
  		}
167
  	}
168
  	if(empty($multiple))
169
  		$item = $entry->single();
170
  	else
171
  	  if (!$filter_query)
172
    		$item = $entry->multiple( $multiple );
173
      else
174
        $item = $entry->multiple( $multiple, 10 );
175
  
176
    // Bail if entry display returned false
177
    if (!$item) {
178
      continue;
179
    }
180
    $ul .= "\n\t<li class='$entry->feed_type feed$entry->feed_id'>$item</li>";
181
182
  	#TODO: this is temporary
183
  	if(!isset($count)) $count = 0;
184
  	$count++;
185
  	if($count > $max)
186
  		break;  		
187
  }
188
  $ul .= "\n</ul>";
189
  return $ul;
190
}