first import
This commit is contained in:
339
sites/all/modules/twitter/LICENSE.txt
Normal file
339
sites/all/modules/twitter/LICENSE.txt
Normal file
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
54
sites/all/modules/twitter/README.txt
Normal file
54
sites/all/modules/twitter/README.txt
Normal file
@@ -0,0 +1,54 @@
|
||||
Introduction
|
||||
============
|
||||
Twitter module allows listing tweets in blocks or pages. Its integration with Views opens the
|
||||
door to all sorts of formatting (ie. as an automatic slideshow with views_slideshow). It also
|
||||
provides useful input filters to easily link Twitter accounts and searches within text.
|
||||
|
||||
Twitter's submodules allow posting to twitter, executing actions/rules when tweeting or login
|
||||
with a Twitter account.
|
||||
|
||||
OAuth
|
||||
=====
|
||||
Except for just listing tweets, OAuth module is required to authenticate against Twitter. If you
|
||||
just want to list tweets in a block, follow the steps at http://drupal.org/node/1253026.
|
||||
|
||||
When you download the OAuth module, get the latest stable release available at http://drupal.org/project/oauth
|
||||
|
||||
Once OAuth has been enabled, go to admin/config/services/twitter and follow instructions.
|
||||
|
||||
How to add a Twitter account to a Drupal user account
|
||||
=====================================================
|
||||
Read http://drupal.org/node/1253026 for details.
|
||||
|
||||
How to use the username and hashtag input filters
|
||||
=================================================
|
||||
1. Go to admin/config/content/formats.
|
||||
2. Select the text format where you want to use the filters.
|
||||
3. At "Enabled filters" check the Twitter converters.
|
||||
|
||||
After that, clear cache and try to create a page with the following body:
|
||||
|
||||
#drupal @drupal
|
||||
|
||||
The above links to a search in Twitter over the #drupal tag and a to the @drupal profile.
|
||||
These filters are avilable when configuring a tweets Views.
|
||||
|
||||
How to post to Twitter
|
||||
======================
|
||||
1. Read the OAuth section to install and configure OAuth.
|
||||
2. Once OAuth has been configured, go to admin/config/services/twitter/post and select from which
|
||||
node types a user may post to Twitter and the default message.
|
||||
3. Verify permissions at admin/people/permissions.
|
||||
4. Add a Twitter account and try to edit or post content.
|
||||
|
||||
How to sign in with Twitter
|
||||
===========================
|
||||
Existing and new users can sign in with Twitter by enabling the twitter_signin module. The following scenarios are being contemplated so far:
|
||||
|
||||
* A visitor logs in with his Twitter account and, once authenticated at Twitter.com, he fills in
|
||||
his email in the Drupal registration form and receives an email to log in and set his account
|
||||
password.
|
||||
* An existing user signs in with Twitter and then logs in into his Drupal user account. This results
|
||||
in the Twitter account getting related to the user account so next time Twitter sign in will work.
|
||||
* An existing user with an already configured Twitter account can log in automatically by clicking
|
||||
on the Sign in with Twitter button.
|
6
sites/all/modules/twitter/TODO.txt
Normal file
6
sites/all/modules/twitter/TODO.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
## Things left to do before release
|
||||
|
||||
* Migrate twitter_actions to new API
|
||||
* Implement the twitter search API
|
||||
* Implement geo features in the API & integrate with location/geo
|
||||
* Implement support for DMs (direct messages)
|
62
sites/all/modules/twitter/tests/core.test
Normal file
62
sites/all/modules/twitter/tests/core.test
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Functional tests for the twitter Module.
|
||||
*/
|
||||
|
||||
class TwitterTest extends DrupalWebTestCase {
|
||||
/*'
|
||||
* The getInfo() method provides information about the test.
|
||||
* In order for the test to be run, the getInfo() method needs
|
||||
* to be implemented.
|
||||
*/
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => t('Main functionality'),
|
||||
'description' => t('Tests main module functionality.'),
|
||||
'group' => t('Twitter'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the testing environment
|
||||
*/
|
||||
function setUp() {
|
||||
parent::setUp('twitter', 'views');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests account addition without Oauth module activated
|
||||
*/
|
||||
public function testAccountAdditionNoOauth() {
|
||||
// Create user
|
||||
$this->user = $this->drupalCreateUser(array(
|
||||
'add twitter accounts',
|
||||
'import own tweets',
|
||||
));
|
||||
$this->drupalLogin($this->user);
|
||||
|
||||
// Add a Twitter account
|
||||
$edit = array(
|
||||
'screen_name' => 'drupal',
|
||||
);
|
||||
$this->drupalPost('user/' . $this->user->uid . '/edit/twitter',
|
||||
$edit, t('Add account'));
|
||||
$this->assertLink('drupal', 0,
|
||||
t('Twitter account was added successfully'));
|
||||
|
||||
// Load tweets
|
||||
twitter_cron();
|
||||
$this->drupalGet('user/' . $this->user->uid . '/tweets');
|
||||
$elements = $this->xpath('//div[contains(@class, "view-tweets")]/div/table');
|
||||
$this->assertTrue(count($elements), 'Tweets were loaded successfully.');
|
||||
// Delete the Twitter account
|
||||
$edit = array(
|
||||
'accounts[0][delete]' => 1,
|
||||
);
|
||||
$this->drupalPost('user/' . $this->user->uid . '/edit/twitter',
|
||||
$edit, t('Save changes'));
|
||||
$this->assertText(t('The Twitter account was deleted.'));
|
||||
}
|
||||
}
|
71
sites/all/modules/twitter/tests/input_filters.test
Normal file
71
sites/all/modules/twitter/tests/input_filters.test
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Functional tests for the input filters of the twitter module.
|
||||
*/
|
||||
|
||||
class TwitterInputFilterTest extends DrupalWebTestCase {
|
||||
/*'
|
||||
* The getInfo() method provides information about the test.
|
||||
* In order for the test to be run, the getInfo() method needs
|
||||
* to be implemented.
|
||||
*/
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => t('Input filters'),
|
||||
'description' => t('Tests input filters provided by the Twitter module.'),
|
||||
'group' => t('Twitter'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the testing environment
|
||||
*/
|
||||
function setUp() {
|
||||
parent::setUp('twitter');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests input filters
|
||||
*/
|
||||
public function testInputFilters() {
|
||||
// Create user
|
||||
$this->privileged_user = $this->drupalCreateUser(array(
|
||||
'bypass node access',
|
||||
'administer filters',
|
||||
));
|
||||
$this->drupalLogin($this->privileged_user);
|
||||
|
||||
// Activate twitter input filters
|
||||
$edit = array(
|
||||
'filters[twitter_username][status]' => 1,
|
||||
'filters[twitter_username][weight]' => 0,
|
||||
'filters[twitter_hashtag][status]' => 1,
|
||||
'filters[twitter_hashtag][weight]' => 1,
|
||||
'filters[filter_url][weight]' => 2,
|
||||
'filters[filter_html][weight]' => 3,
|
||||
'filters[filter_autop][weight]' => 4,
|
||||
'filters[filter_htmlcorrector][weight]' => 5,
|
||||
);
|
||||
$this->drupalPost('admin/config/content/formats/filtered_html', $edit, t('Save configuration'));
|
||||
$this->assertText(t('The text format Filtered HTML has been updated.'));
|
||||
$this->drupalGet('admin/config/content/formats/filtered_html');
|
||||
$this->assertFieldChecked('edit-filters-twitter-username-status',
|
||||
t('Twitter username input filter has been activated'));
|
||||
$this->assertFieldChecked('edit-filters-twitter-hashtag-status',
|
||||
t('Twitter hashtag input filter has been activated'));
|
||||
|
||||
// Create a page so we can evaluate the filters
|
||||
$search = '#drupal';
|
||||
$username = '@drupal';
|
||||
$edit = array();
|
||||
$edit['title'] = t('Test page');
|
||||
$edit['body[und][0][value]'] = t('This is a search over #drupal tag. There is also a link ' .
|
||||
' to a Twitter account here: @drupal.');
|
||||
$this->drupalPost('node/add/page', $edit, t('Save'));
|
||||
$this->assertText(t('Basic page @title has been created.', array('@title' => $edit['title'])));
|
||||
$this->assertLink($search, 0, t('Twitter search input filter was created successfully.'));
|
||||
$this->assertLink($username, 0, t('Twitter username input filter was created successfully.'));
|
||||
}
|
||||
}
|
169
sites/all/modules/twitter/twitter.inc
Normal file
169
sites/all/modules/twitter/twitter.inc
Normal file
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Twitter API functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Connect to the API using the 'proper' version (Oauth vs. standard)
|
||||
*/
|
||||
function twitter_connect($account) {
|
||||
$auth = $account->get_auth();
|
||||
if (_twitter_use_oauth() && $auth['oauth_token'] && $auth['oauth_token_secret']) {
|
||||
module_load_include('lib.php', 'oauth_common');
|
||||
return new TwitterOAuth(variable_get('twitter_consumer_key', ''), variable_get('twitter_consumer_secret', ''),
|
||||
$auth['oauth_token'], $auth['oauth_token_secret']);
|
||||
}
|
||||
else if ($auth['password']) {
|
||||
return new Twitter($account->screen_name, $auth['password']);
|
||||
}
|
||||
else {
|
||||
return new Twitter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a TwitterUser object to {twitter_account}
|
||||
*/
|
||||
function twitter_account_save($twitter_user, $save_auth = FALSE, $account = NULL) {
|
||||
$values = (array) $twitter_user;
|
||||
$values['twitter_uid'] = $values['id'];
|
||||
// bool => int for DB storage
|
||||
foreach (array('protected', 'verified', 'profile_background_tile') as $k) {
|
||||
if (isset($values[$k])) {
|
||||
$values[$k] = (int) $values[$k];
|
||||
}
|
||||
}
|
||||
|
||||
if ($save_auth) {
|
||||
$values += $twitter_user->get_auth();
|
||||
if (empty($account)) {
|
||||
global $user;
|
||||
$account = $user;
|
||||
}
|
||||
$values['uid'] = $account->uid;
|
||||
}
|
||||
$schema = drupal_get_schema('twitter_account');
|
||||
foreach ($values as $k => $v) {
|
||||
if (!isset($schema['fields'][$k])) {
|
||||
unset($values[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
db_merge('twitter_account')
|
||||
->key(array('twitter_uid' => $values['twitter_uid']))
|
||||
->fields($values)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a Twitter account from {twitter_account}.
|
||||
*
|
||||
* @param $id
|
||||
* Twitter UID
|
||||
*
|
||||
* @return
|
||||
* TwitterUser object
|
||||
*
|
||||
*/
|
||||
function twitter_account_load($id) {
|
||||
if ( $values = db_query("SELECT * FROM {twitter_account} WHERE twitter_uid = :twitter_uid", array(':twitter_uid' => $id))->fetchAssoc() ) {
|
||||
$values['id'] = $values['twitter_uid'];
|
||||
$account = new TwitterUser($values);
|
||||
$account->set_auth($values);
|
||||
$account->uid = $values['uid'];
|
||||
$account->import = $values['import'];
|
||||
$account->is_global = $values['is_global'];
|
||||
return $account;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a TwitterStatus object to {twitter}
|
||||
*/
|
||||
function twitter_status_save($status) {
|
||||
$status = array(
|
||||
'twitter_id' => $status->id,
|
||||
'screen_name' => $status->user->screen_name,
|
||||
'created_time' => strtotime($status->created_at),
|
||||
'text' => $status->text,
|
||||
'source' => $status->source,
|
||||
'in_reply_to_status_id' => ($status->in_reply_to_status_id > 0) ? (string) $status->in_reply_to_status_id : NULL,
|
||||
'in_reply_to_user_id' => (int) $status->in_reply_to_user_id,
|
||||
'in_reply_to_screen_name' => $status->in_reply_to_screen_name,
|
||||
'truncated' => (int) $status->truncated,
|
||||
);
|
||||
db_merge('twitter')
|
||||
->key(array('twitter_id' => $status['twitter_id']))
|
||||
->fields($status)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Post a message to twitter
|
||||
*/
|
||||
function twitter_set_status($twitter_account, $status) {
|
||||
$twitter = twitter_connect($twitter_account);
|
||||
$twitter->status_update($status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a user's timeline
|
||||
*/
|
||||
function twitter_fetch_user_timeline($id) {
|
||||
$account = twitter_account_load($id);
|
||||
|
||||
$since = db_query("SELECT MAX(twitter_id) FROM {twitter} WHERE screen_name = :screen_name", array(':screen_name' => $account->screen_name))->fetchField();
|
||||
|
||||
$twitter = twitter_connect($account);
|
||||
|
||||
$params = array();
|
||||
if ($since) {
|
||||
$params['since_id'] = $since;
|
||||
}
|
||||
|
||||
$statuses = $twitter->user_timeline($account->id, $params, $account->protected);
|
||||
foreach ($statuses as $status) {
|
||||
twitter_status_save($status);
|
||||
}
|
||||
|
||||
if (count($statuses) > 0) {
|
||||
twitter_account_save($statuses[0]->user);
|
||||
}
|
||||
|
||||
db_update('twitter_account')
|
||||
->fields(array(
|
||||
'last_refresh' => REQUEST_TIME,
|
||||
))
|
||||
->condition('twitter_uid', $account->id)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a twitter account and its statuses.
|
||||
*
|
||||
* @param $twitter_uid
|
||||
* An integer with the Twitter UID.
|
||||
*
|
||||
* @param $screen_name
|
||||
* Optional string with the user name.
|
||||
*/
|
||||
function twitter_account_delete($twitter_uid) {
|
||||
$account = twitter_account_load($twitter_uid);
|
||||
|
||||
// Delete from {twitter_account}.
|
||||
$query = db_delete('twitter_account');
|
||||
$query->conditions('twitter_uid', $twitter_uid);
|
||||
$query->execute();
|
||||
|
||||
// Delete from {twitter}.
|
||||
$query = db_delete('twitter');
|
||||
$query->conditions('screen_name', $account->screen_name);
|
||||
$query->execute();
|
||||
|
||||
// Delete from {twitter_account}.
|
||||
$query = db_delete('authmap');
|
||||
$query->conditions('authname', $twitter_uid);
|
||||
$query->conditions('module', 'twitter');
|
||||
$query->execute();
|
||||
}
|
16
sites/all/modules/twitter/twitter.info
Normal file
16
sites/all/modules/twitter/twitter.info
Normal file
@@ -0,0 +1,16 @@
|
||||
name = Twitter
|
||||
description = Adds integration with the Twitter microblogging service.
|
||||
php = 5.1
|
||||
core = 7.x
|
||||
files[] = twitter.lib.php
|
||||
files[] = twitter_views_field_handlers.inc
|
||||
files[] = tests/core.test
|
||||
files[] = tests/input_filters.test
|
||||
configure = admin/config/services/twitter
|
||||
|
||||
; Information added by drupal.org packaging script on 2011-12-03
|
||||
version = "7.x-3.0-beta4"
|
||||
core = "7.x"
|
||||
project = "twitter"
|
||||
datestamp = "1322940643"
|
||||
|
326
sites/all/modules/twitter/twitter.install
Normal file
326
sites/all/modules/twitter/twitter.install
Normal file
@@ -0,0 +1,326 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the twitter module.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_schema().
|
||||
*/
|
||||
function twitter_schema() {
|
||||
$schema['twitter'] = array(
|
||||
'description' => "Stores individual Twitter posts.",
|
||||
'fields' => array(
|
||||
'twitter_id' => array(
|
||||
'description' => "Unique identifier for each {twitter} post.",
|
||||
'type' => 'numeric',
|
||||
'unsigned' => TRUE,
|
||||
'precision' => 20,
|
||||
'scale' => 0,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
'screen_name' => array(
|
||||
'description' => "Screen Name of the {twitter_account} user.",
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'created_at' => array(
|
||||
'description' => "Date and time the {twitter} post was created.",
|
||||
'type' => 'varchar',
|
||||
'length' => 64,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'created_time' => array(
|
||||
'description' => "A duplicate of {twitter}.created_at in UNIX timestamp format.",
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'text' => array(
|
||||
'description' => "The text of the {twitter} post.",
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
'source' => array(
|
||||
'description' => "The application that created the {twitter} post.",
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
'in_reply_to_status_id' => array(
|
||||
'description' => "Unique identifier of a status this {twitter} post was replying to.",
|
||||
'type' => 'numeric',
|
||||
'unsigned' => TRUE,
|
||||
'precision' => 20,
|
||||
'scale' => 0,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
'in_reply_to_user_id' => array(
|
||||
'description' => "Unique identifier for the {twitter_account} this post was replying to.",
|
||||
'type' => 'numeric',
|
||||
'unsigned' => TRUE,
|
||||
'precision' => 20,
|
||||
'scale' => 0,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
'in_reply_to_screen_name' => array(
|
||||
'description' => "Screen name of the {twitter} user this post was replying to.",
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
'truncated' => array(
|
||||
'description' => "Boolean flag indicating whether the {twitter} status was cut off to fit in the 140 character limit.",
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
),
|
||||
'indexes' => array('screen_name' => array('screen_name')),
|
||||
'primary key' => array('twitter_id'),
|
||||
);
|
||||
|
||||
$schema['twitter_account'] = array(
|
||||
'description' => "Stores information on specific Twitter user accounts.",
|
||||
'fields' => array(
|
||||
'twitter_uid' => array(
|
||||
'description' => "The unique identifier of the {twitter_account}.",
|
||||
'type' => 'numeric',
|
||||
'unsigned' => TRUE,
|
||||
'precision' => 20,
|
||||
'scale' => 0,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
'uid' => array(
|
||||
'description' => "The {users}.uid of the owner of this account",
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'size' => 'big',
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'host' => array(
|
||||
'description' => 'The host for this account can be a laconi.ca instance',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
),
|
||||
'screen_name' => array(
|
||||
'description' => "The unique login name of the {twitter_account} user.",
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
),
|
||||
'password' => array(
|
||||
'description' => "The password for the Twitter account.",
|
||||
'type' => 'varchar',
|
||||
'length' => 64,
|
||||
),
|
||||
'oauth_token' => array(
|
||||
'description' => 'The token_key for oauth-based access.',
|
||||
'type' => 'varchar',
|
||||
'length' => 64,
|
||||
),
|
||||
'oauth_token_secret' => array(
|
||||
'description' => 'The token_secret for oauth-based access.',
|
||||
'type' => 'varchar',
|
||||
'length' => 64,
|
||||
),
|
||||
'name' => array(
|
||||
'description' => "The full name of the {twitter_account} user.",
|
||||
'type' => 'varchar',
|
||||
'length' => 64,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'description' => array(
|
||||
'description' => "The description/biography associated with the {twitter_account}.",
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
),
|
||||
'location' => array(
|
||||
'description' => "The location of the {twitter_account}'s owner.",
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
),
|
||||
'followers_count' => array(
|
||||
'description' => "The number of users following this {twitter_account}.",
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
'friends_count' => array(
|
||||
'description' => "The number of users this {twitter_account} is following.",
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
'statuses_count' => array(
|
||||
'description' => "The total number of status updates performed by a user, excluding direct messages sent.",
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
'favourites_count' => array(
|
||||
'description' => "The number of statuses a user has marked as favorite.",
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
'url' => array(
|
||||
'description' => "The url of the {twitter_account}'s home page.",
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
),
|
||||
'profile_image_url' => array(
|
||||
'description' => "The url of the {twitter_account}'s profile image.",
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
),
|
||||
'protected' => array(
|
||||
'description' => "Boolean flag indicating whether the {twitter_account}'s posts are publicly accessible.",
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
'profile_background_color' => array(
|
||||
'description' => "hex RGB value for a user's background color",
|
||||
'type' => 'varchar',
|
||||
'length' => 6,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'profile_text_color' => array(
|
||||
'description' => "hex RGB value for a user's text color",
|
||||
'type' => 'varchar',
|
||||
'length' => 6,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'profile_link_color' => array(
|
||||
'description' => "hex RGB value for a user's link color",
|
||||
'type' => 'varchar',
|
||||
'length' => 6,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'profile_sidebar_fill_color' => array(
|
||||
'description' => "hex RGB value for a user's sidebar color",
|
||||
'type' => 'varchar',
|
||||
'length' => 6,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'profile_sidebar_border_color' => array(
|
||||
'description' => "hex RGB value for a user's border color",
|
||||
'type' => 'varchar',
|
||||
'length' => 6,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'profile_background_image_url' => array(
|
||||
'description' => "The url of the {twitter_account}'s profile image.",
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
),
|
||||
'profile_background_tile' => array(
|
||||
'description' => "Boolean indicating if a user's background is tiled.",
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 1,
|
||||
),
|
||||
'verified' => array(
|
||||
'description' => "Indicates if a user is verified.",
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 1,
|
||||
),
|
||||
'created_at' => array(
|
||||
'description' => "Date and time the {twitter_account} was created.",
|
||||
'type' => 'varchar',
|
||||
'length' => 64,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'created_time' => array(
|
||||
'description' => "A duplicate of {twitter_account}.created_at in UNIX timestamp format.",
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'utc_offset' => array(
|
||||
'description' => "A duplicate of {twitter_account}.created_at in UNIX timestamp format.",
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'import' => array(
|
||||
'description' => "Boolean flag indicating whether the {twitter_user}'s posts should be pulled in by the site.",
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 1,
|
||||
),
|
||||
'last_refresh' => array(
|
||||
'description' => "A UNIX timestamp marking the date Twitter statuses were last fetched on.",
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
'is_global' => array(
|
||||
'description' => "Boolean flag indicating if this account is available for global use",
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
),
|
||||
'indexes' => array('screen_name' => array('screen_name')),
|
||||
'primary key' => array('twitter_uid'),
|
||||
);
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
function twitter_install() {
|
||||
// Set the weight to 3, making it heavier than Pathauto.
|
||||
db_update('system')
|
||||
->fields(array(
|
||||
'weight' => 3,
|
||||
))
|
||||
->condition('type', 'module')
|
||||
->condition('name', 'twitter')
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uninstall().
|
||||
*/
|
||||
function twitter_uninstall() {
|
||||
// Remove variables
|
||||
variable_del('twitter_import');
|
||||
variable_del('twitter_expire');
|
||||
variable_del('twitter_consumer_key');
|
||||
variable_del('twitter_consumer_secret');
|
||||
variable_del('twitter_post_types');
|
||||
variable_del('twitter_host');
|
||||
variable_del('twitter_post_default_format');
|
||||
variable_del('twitter_signin_button');
|
||||
variable_del('twitter_signin_register');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_update_last_removed().
|
||||
*/
|
||||
function twitter_update_last_removed() {
|
||||
return 6005;
|
||||
}
|
535
sites/all/modules/twitter/twitter.lib.php
Normal file
535
sites/all/modules/twitter/twitter.lib.php
Normal file
@@ -0,0 +1,535 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Classes to implement the full Twitter API
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class TwitterConfig
|
||||
*
|
||||
* Singleton which stores common configuration
|
||||
* @see http://php.net/manual/en/language.oop5.patterns.php
|
||||
*/
|
||||
class TwitterConf {
|
||||
private static $instance;
|
||||
private $attributes = array(
|
||||
'host' => 'twitter.com',
|
||||
'api' => 'api.twitter.com',
|
||||
'search' => 'search.twitter.com',
|
||||
'tiny_url' => 'tinyurl.com',
|
||||
);
|
||||
|
||||
private function __construct() {}
|
||||
|
||||
public static function instance() {
|
||||
if (!isset(self::$instance)) {
|
||||
$className = __CLASS__;
|
||||
self::$instance = new $className;
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic getter
|
||||
*
|
||||
* @param $attribute
|
||||
* string attribute name to return
|
||||
* @return
|
||||
* mixed value or NULL
|
||||
*/
|
||||
public function get($attribute) {
|
||||
if (array_key_exists($attribute, $this->attributes)) {
|
||||
return $this->attributes[$attribute];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic setter
|
||||
* @param $attribute
|
||||
* string attribute name to be set
|
||||
* @param $value
|
||||
* mixed value
|
||||
*/
|
||||
public function set($attribute, $value) {
|
||||
if (array_key_exists($attribute, $this->attributes)) {
|
||||
$this->attributes[$attribute] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception handling class.
|
||||
*/
|
||||
class TwitterException extends Exception {}
|
||||
|
||||
/**
|
||||
* Primary Twitter API implementation class
|
||||
* Supports the full REST API for twitter.
|
||||
*/
|
||||
class Twitter {
|
||||
|
||||
/**
|
||||
* @var $format API format to use: can be json or xml
|
||||
*/
|
||||
protected $format = 'json';
|
||||
|
||||
/**
|
||||
* @var $source the twitter api 'source'
|
||||
*/
|
||||
protected $source = 'drupal';
|
||||
|
||||
/**
|
||||
* @var $username Twitter username to use for authenticated requests
|
||||
*/
|
||||
protected $username;
|
||||
|
||||
/**
|
||||
* @var $password Twitter password to use for authenticated requests
|
||||
*/
|
||||
protected $password;
|
||||
|
||||
/**
|
||||
* Constructor for the Twitter class
|
||||
*/
|
||||
public function __construct($username = NULL, $password = NULL) {
|
||||
if (!empty($username) && !empty($password)) {
|
||||
$this->set_auth($username, $password);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the username and password
|
||||
*/
|
||||
public function set_auth($username, $password) {
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of TwitterStatus objects from an API endpoint
|
||||
*/
|
||||
protected function get_statuses($path, $params = array(), $use_auth = FALSE) {
|
||||
$values = $this->call($path, $params, 'GET', $use_auth);
|
||||
// Check on successfull call
|
||||
if ($values) {
|
||||
$statuses = array();
|
||||
foreach ($values as $status) {
|
||||
$statuses[] = new TwitterStatus($status);
|
||||
}
|
||||
return $statuses;
|
||||
}
|
||||
// Call might return FALSE , e.g. on failed authentication
|
||||
else {
|
||||
// As call allready throws an exception, we can return an empty array to
|
||||
// break no code.
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the public timeline
|
||||
*
|
||||
* @see http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-statuses-public_timeline
|
||||
*/
|
||||
public function public_timeline() {
|
||||
return $this->get_statuses('statuses/public_timeline');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the authenticated user's friends timeline
|
||||
*
|
||||
* @see http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-statuses-friends_timeline
|
||||
*/
|
||||
public function friends_timeline($params = array()) {
|
||||
return $this->get_statuses('statuses/friends_timeline', $params, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a user's timeline
|
||||
*
|
||||
* @see http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-statuses-user_timeline
|
||||
*/
|
||||
public function user_timeline($id, $params = array(), $use_auth = FALSE) {
|
||||
if (is_numeric($id)) {
|
||||
$params['user_id'] = $id;
|
||||
}
|
||||
else {
|
||||
$params['screen_name'] = $id;
|
||||
}
|
||||
|
||||
return $this->get_statuses('statuses/user_timeline', $params, $use_auth);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-statuses-mentions
|
||||
*/
|
||||
public function mentions($params = array()) {
|
||||
return $this->get_statuses('statuses/mentions', $params, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-statuses%C2%A0update
|
||||
*/
|
||||
public function status_update($status, $params = array()) {
|
||||
$params['status'] = $status;
|
||||
if ($this->source) {
|
||||
$params['source'] = $this->source;
|
||||
}
|
||||
$values = $this->call('statuses/update', $params, 'POST', TRUE);
|
||||
|
||||
return new TwitterStatus($values);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @see http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-users%C2%A0show
|
||||
*/
|
||||
public function users_show($id, $use_auth = TRUE) {
|
||||
$params = array();
|
||||
if (is_numeric($id)) {
|
||||
$params['user_id'] = $id;
|
||||
}
|
||||
else {
|
||||
$params['screen_name'] = $id;
|
||||
}
|
||||
|
||||
$values = $this->call('users/show', $params, 'GET', $use_auth);
|
||||
return new TwitterUser($values);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-account%C2%A0verify_credentials
|
||||
*/
|
||||
public function verify_credentials() {
|
||||
$values = $this->call('account/verify_credentials', array(), 'GET', TRUE);
|
||||
if (!$values) {
|
||||
return FALSE;
|
||||
}
|
||||
return new TwitterUser($values);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method for calling any twitter api resource
|
||||
*/
|
||||
public function call($path, $params = array(), $method = 'GET', $use_auth = FALSE) {
|
||||
$url = $this->create_url($path);
|
||||
|
||||
try {
|
||||
if ($use_auth) {
|
||||
$response = $this->auth_request($url, $params, $method);
|
||||
}
|
||||
else {
|
||||
$response = $this->request($url, $params, $method);
|
||||
}
|
||||
}
|
||||
catch (TwitterException $e) {
|
||||
watchdog('twitter', '!message', array('!message' => $e->__toString()), WATCHDOG_ERROR);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!$response) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return $this->parse_response($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an authentication required request.
|
||||
*/
|
||||
protected function auth_request($path, $params = array(), $method = 'GET') {
|
||||
if (empty($this->username) || empty($this->password)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->request($path, $params, $method, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a request
|
||||
*/
|
||||
protected function request($url, $params = array(), $method = 'GET', $use_auth = FALSE) {
|
||||
$data = '';
|
||||
if (count($params) > 0) {
|
||||
if ($method == 'GET') {
|
||||
$url .= '?'. http_build_query($params, '', '&');
|
||||
}
|
||||
else {
|
||||
$data = http_build_query($params, '', '&');
|
||||
}
|
||||
}
|
||||
|
||||
$headers = array();
|
||||
|
||||
if ($use_auth) {
|
||||
$headers['Authorization'] = 'Basic '. base64_encode($this->username .':'. $this->password);
|
||||
$headers['Content-type'] = 'application/x-www-form-urlencoded';
|
||||
}
|
||||
|
||||
$response = drupal_http_request($url, array('headers' => $headers, 'method' => $method, 'data' => $data));
|
||||
if (!isset($response->error)) {
|
||||
return $response->data;
|
||||
}
|
||||
else {
|
||||
$error = $response->error;
|
||||
$data = $this->parse_response($response->data);
|
||||
if (isset($data['error'])) {
|
||||
$error = $data['error'];
|
||||
}
|
||||
throw new TwitterException($error);
|
||||
}
|
||||
}
|
||||
|
||||
protected function parse_response($response, $format = NULL) {
|
||||
if (empty($format)) {
|
||||
$format = $this->format;
|
||||
}
|
||||
|
||||
switch ($format) {
|
||||
case 'json':
|
||||
// http://drupal.org/node/985544 - json_decode large integer issue
|
||||
$length = strlen(PHP_INT_MAX);
|
||||
$response = preg_replace('/"(id|in_reply_to_status_id)":(\d{' . $length . ',})/', '"\1":"\2"', $response);
|
||||
return json_decode($response, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
protected function create_url($path, $format = NULL) {
|
||||
if (is_null($format)) {
|
||||
$format = $this->format;
|
||||
}
|
||||
$conf = TwitterConf::instance();
|
||||
$url = 'http://'. $conf->get('api') .'/'. $path;
|
||||
if (!empty($format)) {
|
||||
$url .= '.'. $this->format;
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class to provide OAuth enabled access to the twitter API
|
||||
*/
|
||||
class TwitterOAuth extends Twitter {
|
||||
|
||||
protected $signature_method;
|
||||
|
||||
protected $consumer;
|
||||
|
||||
protected $token;
|
||||
|
||||
public function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) {
|
||||
$this->signature_method = new OAuthSignatureMethod_HMAC_SHA1();
|
||||
$this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);
|
||||
if (!empty($oauth_token) && !empty($oauth_token_secret)) {
|
||||
$this->token = new OAuthConsumer($oauth_token, $oauth_token_secret);
|
||||
}
|
||||
}
|
||||
|
||||
public function get_request_token() {
|
||||
$url = $this->create_url('oauth/request_token', '');
|
||||
try {
|
||||
$response = $this->auth_request($url);
|
||||
}
|
||||
catch (TwitterException $e) {
|
||||
}
|
||||
parse_str($response, $token);
|
||||
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
|
||||
return $token;
|
||||
}
|
||||
|
||||
public function get_authorize_url($token) {
|
||||
$url = $this->create_url('oauth/authorize', '');
|
||||
$url.= '?oauth_token=' . $token['oauth_token'];
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function get_authenticate_url($token) {
|
||||
$url = $this->create_url('oauth/authenticate', '');
|
||||
$url.= '?oauth_token=' . $token['oauth_token'];
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function get_access_token() {
|
||||
$url = $this->create_url('oauth/access_token', '');
|
||||
try {
|
||||
$response = $this->auth_request($url);
|
||||
}
|
||||
catch (TwitterException $e) {
|
||||
}
|
||||
parse_str($response, $token);
|
||||
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
|
||||
return $token;
|
||||
}
|
||||
|
||||
public function auth_request($url, $params = array(), $method = 'GET') {
|
||||
$request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $params);
|
||||
$request->sign_request($this->signature_method, $this->consumer, $this->token);
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
return $this->request($request->to_url());
|
||||
case 'POST':
|
||||
return $this->request($request->get_normalized_http_url(), $request->get_parameters(), 'POST');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Twitter search is not used in this module yet
|
||||
*/
|
||||
class TwitterSearch extends Twitter {
|
||||
public function search($params = array()) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for containing an individual twitter status.
|
||||
*/
|
||||
class TwitterStatus {
|
||||
/**
|
||||
* @var created_at
|
||||
*/
|
||||
public $created_at;
|
||||
|
||||
public $id;
|
||||
|
||||
public $text;
|
||||
|
||||
public $source;
|
||||
|
||||
public $truncated;
|
||||
|
||||
public $favorited;
|
||||
|
||||
public $in_reply_to_status_id;
|
||||
|
||||
public $in_reply_to_user_id;
|
||||
|
||||
public $in_reply_to_screen_name;
|
||||
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Constructor for TwitterStatus
|
||||
*/
|
||||
public function __construct($values = array()) {
|
||||
$this->created_at = $values['created_at'];
|
||||
$this->id = $values['id'];
|
||||
$this->text = $values['text'];
|
||||
$this->source = $values['source'];
|
||||
$this->truncated = $values['truncated'];
|
||||
$this->favorited = $values['favorited'];
|
||||
$this->in_reply_to_status_id = $values['in_reply_to_status_id'];
|
||||
$this->in_reply_to_user_id = $values['in_reply_to_user_id'];
|
||||
$this->in_reply_to_screen_name = $values['in_reply_to_screen_name'];
|
||||
if (isset($values['user'])) {
|
||||
$this->user = new TwitterUser($values['user']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TwitterUser {
|
||||
|
||||
public $id;
|
||||
|
||||
public $screen_name;
|
||||
|
||||
public $name;
|
||||
|
||||
public $location;
|
||||
|
||||
public $description;
|
||||
|
||||
public $followers_count;
|
||||
|
||||
public $friends_count;
|
||||
|
||||
public $statuses_count;
|
||||
|
||||
public $favourites_count;
|
||||
|
||||
public $url;
|
||||
|
||||
public $protected;
|
||||
|
||||
public $profile_image_url;
|
||||
|
||||
public $profile_background_color;
|
||||
|
||||
public $profile_text_color;
|
||||
|
||||
public $profile_link_color;
|
||||
|
||||
public $profile_sidebar_fill_color;
|
||||
|
||||
public $profile_sidebar_border_color;
|
||||
|
||||
public $profile_background_image_url;
|
||||
|
||||
public $profile_background_tile;
|
||||
|
||||
public $verified;
|
||||
|
||||
public $created_at;
|
||||
|
||||
public $created_time;
|
||||
|
||||
public $utc_offset;
|
||||
|
||||
public $status;
|
||||
|
||||
protected $password;
|
||||
|
||||
protected $oauth_token;
|
||||
|
||||
protected $oauth_token_secret;
|
||||
|
||||
public function __construct($values = array()) {
|
||||
$this->id = $values['id'];
|
||||
$this->screen_name = $values['screen_name'];
|
||||
$this->name = $values['name'];
|
||||
$this->location = $values['location'];
|
||||
$this->description = $values['description'];
|
||||
$this->url = $values['url'];
|
||||
$this->followers_count = $values['followers_count'];
|
||||
$this->friends_count = $values['friends_count'];
|
||||
$this->statuses_count = $values['statuses_count'];
|
||||
$this->favourites_count = $values['favourites_count'];
|
||||
$this->protected = $values['protected'];
|
||||
$this->profile_image_url = $values['profile_image_url'];
|
||||
$this->profile_background_color = $values['profile_background_color'];
|
||||
$this->profile_text_color = $values['profile_text_color'];
|
||||
$this->profile_link_color = $values['profile_link_color'];
|
||||
$this->profile_sidebar_fill_color = $values['profile_sidebar_fill_color'];
|
||||
$this->profile_sidebar_border_color = $values['profile_sidebar_border_color'];
|
||||
$this->profile_background_image_url = $values['profile_background_image_url'];
|
||||
$this->profile_background_tile = $values['profile_background_tile'];
|
||||
$this->verified = $values['verified'];
|
||||
$this->created_at = $values['created_at'];
|
||||
if ($values['created_at'] && $created_time = strtotime($values['created_at'])) {
|
||||
$this->created_time = $created_time;
|
||||
}
|
||||
$this->utc_offset = $values['utc_offset']?$values['utc_offset']:0;
|
||||
|
||||
if (isset($values['status'])) {
|
||||
$this->status = new TwitterStatus($values['status']);
|
||||
}
|
||||
}
|
||||
|
||||
public function get_auth() {
|
||||
return array('password' => $this->password, 'oauth_token' => $this->oauth_token, 'oauth_token_secret' => $this->oauth_token_secret);
|
||||
}
|
||||
|
||||
public function set_auth($values) {
|
||||
$this->oauth_token = isset($values['oauth_token'])?$values['oauth_token']:NULL;
|
||||
$this->oauth_token_secret = isset($values['oauth_token_secret'])?$values['oauth_token_secret']:NULL;
|
||||
}
|
||||
}
|
289
sites/all/modules/twitter/twitter.module
Normal file
289
sites/all/modules/twitter/twitter.module
Normal file
@@ -0,0 +1,289 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Provides API integration with the Twitter microblogging service.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function twitter_menu() {
|
||||
$items['twitter/oauth'] = array(
|
||||
'title' => 'Twitter',
|
||||
'access callback' => TRUE,
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('twitter_oauth_callback'),
|
||||
'type' => MENU_CALLBACK,
|
||||
'file' => 'twitter.pages.inc',
|
||||
);
|
||||
|
||||
$items['admin/config/services/twitter'] = array(
|
||||
'title' => 'Twitter',
|
||||
'description' => 'Configure integration with Twitter (and compatible) API services.',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('twitter_admin_form'),
|
||||
'access arguments' => array('administer site configuration'),
|
||||
'file' => 'twitter.pages.inc',
|
||||
);
|
||||
|
||||
$items['admin/config/services/twitter/default'] = array(
|
||||
'title' => 'Twitter',
|
||||
'type' => MENU_DEFAULT_LOCAL_TASK,
|
||||
);
|
||||
|
||||
$items['user/%user_category/edit/twitter'] = array(
|
||||
'title' => 'Twitter accounts',
|
||||
'page callback' => 'twitter_user_settings',
|
||||
'page arguments' => array(1),
|
||||
'access callback' => 'twitter_edit_access',
|
||||
'access arguments' => array(1),
|
||||
'load arguments' => array('%map', '%index'),
|
||||
'weight' => 10,
|
||||
'file' => 'twitter.pages.inc',
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
);
|
||||
|
||||
$items['user/%user/edit/twitter/global/%'] = array(
|
||||
'title' => 'Twitter accounts',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('twitter_user_make_global', 1, 5),
|
||||
'access arguments' => array('make twitter accounts global'),
|
||||
'file' => 'twitter.pages.inc',
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access callback for twitter account editing.
|
||||
*/
|
||||
function twitter_edit_access($account) {
|
||||
return user_edit_access($account) && user_access('add twitter accounts');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_permission().
|
||||
*/
|
||||
function twitter_permission() {
|
||||
return array(
|
||||
'add twitter accounts' => array(
|
||||
'title' => t('Add Twitter accounts'),
|
||||
),
|
||||
'use global twitter account' => array(
|
||||
'title' => t('Use the site global Twitter account'),
|
||||
),
|
||||
'make twitter accounts global' => array(
|
||||
'title' => t('Assign a Twitter account as the site global account.'),
|
||||
),
|
||||
'import own tweets' => array(
|
||||
'title' => t('Import own tweets to the site.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_user_categories().
|
||||
*/
|
||||
function twitter_user_categories() {
|
||||
return array(
|
||||
array(
|
||||
'name' => 'twitter',
|
||||
'title' => t('Twitter accounts'),
|
||||
'weight' => 3,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_theme().
|
||||
*/
|
||||
function twitter_theme() {
|
||||
return array(
|
||||
'twitter_account_list_form' => array(
|
||||
'render element' => 'form',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Very lightweight helper function to generate a TinyURL for a given post.
|
||||
*/
|
||||
function twitter_shorten_url($url) {
|
||||
if (module_exists('shorten')) {
|
||||
return shorten_url($url);
|
||||
}
|
||||
else {
|
||||
$conf = TwitterConf::instance();
|
||||
$response = drupal_http_request("http://" . $conf->get('tiny_url') . "/api-create.php?url=" . $url);
|
||||
if ($response->code == 200) {
|
||||
return $response->data;
|
||||
}
|
||||
else {
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_cron().
|
||||
*
|
||||
* Imports new Twitter statuses for site users, and deletes expired tweets.
|
||||
*/
|
||||
function twitter_cron() {
|
||||
if (!variable_get('twitter_import', TRUE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Pull up a list of Twitter accounts that are flagged for updating,
|
||||
// sorted by how long it's been since we last updated them. This ensures
|
||||
// that the most out-of-date accounts get updated first.
|
||||
module_load_include('inc', 'twitter');
|
||||
$result = db_query_range("SELECT twitter_uid FROM {twitter_account} WHERE import = :import ORDER BY last_refresh ASC", 0, 20, array(':import' => 1));
|
||||
foreach ($result as $account) {
|
||||
twitter_fetch_user_timeline($account->twitter_uid);
|
||||
}
|
||||
|
||||
// Nuke old statuses.
|
||||
if ($age = variable_get('twitter_expire', 0)) {
|
||||
db_delete('twitter')
|
||||
->condition('created_time', REQUEST_TIME - $age, '<')
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_filter_info().
|
||||
*/
|
||||
function twitter_filter_info() {
|
||||
$filters['twitter_username'] = array(
|
||||
'title' => t('Twitter @username converter'),
|
||||
'description' => t('Converts Twitter-style @usernames into links to Twitter account pages.'),
|
||||
'process callback' => '_twitter_filter_username',
|
||||
'tips callback' => '_twitter_filter_tip_username',
|
||||
);
|
||||
$filters['twitter_hashtag'] = array(
|
||||
'title' => t('Twitter #hashtag converter'),
|
||||
'description' => t('Converts Twitter-style #hashtags into links to hashtags.org.'),
|
||||
'process callback' => '_twitter_filter_hashtag',
|
||||
'tips callback' => '_twitter_filter_tip_hashtag',
|
||||
);
|
||||
return $filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter tips callback function for $filters[0] in hook_filter_info().
|
||||
*/
|
||||
function _twitter_filter_tip_username($filter, $format, $long = FALSE) {
|
||||
return t('Twitter-style @usernames are linked to their Twitter account pages.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter tips callback function for $filters[1] in hook_filter_info().
|
||||
*/
|
||||
function _twitter_filter_tip_hashtag($format, $long = FALSE) {
|
||||
return t('Twitter-style #hashtags are linked to !url.', array(
|
||||
'!url' => '<a href="http://search.twitter.com/">search.twitter.com</a>')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for twitter @username converter
|
||||
*/
|
||||
function _twitter_filter_username($text, $filter) {
|
||||
$prefix = '@';
|
||||
$conf = TwitterConf::instance();
|
||||
$destination = 'http://' . $conf->get('host') . '/';
|
||||
return _twitter_filter_text($text, $prefix, $destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for twitter #hashtag converter
|
||||
*/
|
||||
function _twitter_filter_hashtag($text, $filter) {
|
||||
$prefix = '#';
|
||||
$conf = TwitterConf::instance();
|
||||
$destination = 'http://' . $conf->get('search') . '/search?q=%23';
|
||||
return _twitter_filter_text($text, $prefix, $destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper function converts Twitter-style @usernames and #hashtags into
|
||||
* actual links.
|
||||
*/
|
||||
function _twitter_filter_text($text, $prefix, $destination) {
|
||||
$matches = array(
|
||||
'/\>' . $prefix . '([a-z0-9_]+)/i',
|
||||
'/^' . $prefix . '([a-z0-9_]+)/i',
|
||||
'/(\s+)' . $prefix . '([a-z0-9_]+)/i',
|
||||
);
|
||||
$replacements = array(
|
||||
'><a href="' . $destination . '/${1}">' . $prefix . '${1}</a>',
|
||||
'<a href="' . $destination . '/${1}">' . $prefix . '${1}</a>',
|
||||
'${1}<a href="' . $destination . '/${2}">' . $prefix . '${2}</a>',
|
||||
);
|
||||
return preg_replace($matches, $replacements, $text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_user_load().
|
||||
*/
|
||||
function twitter_user_load($accounts) {
|
||||
foreach ($accounts as $uid => $account) {
|
||||
$accounts[$uid]->twitter_accounts = module_invoke_all('twitter_accounts', $account);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An implementation of hook_twitter_accounts. We want to move this into a
|
||||
* separate module eventually, but sticking the code here and using a hook
|
||||
* lets other modules solve the 'what accounts can a user post with' problem
|
||||
* in cleaner ways.
|
||||
*
|
||||
* @return
|
||||
* array with Twitter accounts
|
||||
*/
|
||||
function twitter_twitter_accounts($account) {
|
||||
module_load_include('inc', 'twitter');
|
||||
|
||||
$query = db_select('twitter_account', 'ta')
|
||||
->fields('ta', array('twitter_uid'));
|
||||
if (user_access('use global twitter account', $account)) {
|
||||
$or = db_or();
|
||||
$or->condition('ta.uid', $account->uid);
|
||||
$or->condition('ta.is_global', 1);
|
||||
$query->condition($or);
|
||||
}
|
||||
else {
|
||||
$query->condition('ta.uid', $account->uid);
|
||||
}
|
||||
|
||||
$twitter_accounts = array();
|
||||
foreach ($query->execute()->fetchCol() as $twitter_uid) {
|
||||
$twitter_accounts[] = twitter_account_load($twitter_uid);
|
||||
}
|
||||
return $twitter_accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect whether we should use oauth. This can probably just go now :)
|
||||
*/
|
||||
function _twitter_use_oauth() {
|
||||
return module_exists('oauth_common') && variable_get('twitter_consumer_key', '') &&
|
||||
variable_get('twitter_consumer_secret', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_views_api().
|
||||
*/
|
||||
function twitter_views_api() {
|
||||
return array('api' => 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_admin_paths_alter().
|
||||
*
|
||||
* OAuth callback disagrees with overlay.
|
||||
*/
|
||||
function twitter_admin_paths_alter(&$paths) {
|
||||
$paths['user/*/edit/twitter'] = FALSE;
|
||||
}
|
442
sites/all/modules/twitter/twitter.pages.inc
Normal file
442
sites/all/modules/twitter/twitter.pages.inc
Normal file
@@ -0,0 +1,442 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Form builder; Twitter settings form.
|
||||
*/
|
||||
function twitter_admin_form($form, &$form_state) {
|
||||
$form['twitter_import'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Import and display the Twitter statuses of site users who have entered their Twitter account information.'),
|
||||
'#default_value' => variable_get('twitter_import', 1),
|
||||
);
|
||||
$form['twitter_expire'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Delete old statuses'),
|
||||
'#default_value' => variable_get('twitter_expire', 0),
|
||||
'#options' => array(0 => t('Never')) + drupal_map_assoc(array(604800, 2592000, 7776000, 31536000), 'format_interval'),
|
||||
'#states' => array(
|
||||
'visible' => array(
|
||||
':input[name=twitter_import]' => array('checked' => TRUE),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$form['oauth'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('OAuth Settings'),
|
||||
'#access' => module_exists('oauth_common'),
|
||||
'#description' => t('To enable OAuth based access for twitter, you must <a href="@url">register your application</a> with Twitter and add the provided keys here.', array('@url' => 'https://dev.twitter.com/apps/new')),
|
||||
);
|
||||
$form['oauth']['callback_url'] = array(
|
||||
'#type' => 'item',
|
||||
'#title' => t('Callback URL'),
|
||||
'#markup' => url('twitter/oauth', array('absolute' => TRUE)),
|
||||
);
|
||||
$form['oauth']['twitter_consumer_key'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('OAuth Consumer key'),
|
||||
'#default_value' => variable_get('twitter_consumer_key', NULL),
|
||||
);
|
||||
$form['oauth']['twitter_consumer_secret'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('OAuth Consumer secret'),
|
||||
'#default_value' => variable_get('twitter_consumer_secret', NULL),
|
||||
);
|
||||
|
||||
return system_settings_form($form);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Please document this function.
|
||||
* @see http://drupal.org/node/1354
|
||||
*/
|
||||
function twitter_user_settings($account) {
|
||||
module_load_include('inc', 'twitter');
|
||||
|
||||
$output = array();
|
||||
if (!empty($account->twitter_accounts)) {
|
||||
$output['list_form'] = drupal_get_form('twitter_account_list_form', $account->twitter_accounts);
|
||||
}
|
||||
$output['form'] = drupal_get_form('twitter_account_form', $account);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Please document this function.
|
||||
* @see http://drupal.org/node/1354
|
||||
*/
|
||||
function twitter_account_list_form($form, $form_state, $twitter_accounts = array()) {
|
||||
$form['#tree'] = TRUE;
|
||||
$form['accounts'] = array();
|
||||
|
||||
foreach ($twitter_accounts as $twitter_account) {
|
||||
$form['accounts'][] = _twitter_account_list_row($twitter_account);
|
||||
}
|
||||
|
||||
if (!empty($twitter_accounts)) {
|
||||
$form['buttons']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Save changes'),
|
||||
);
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
function _twitter_account_list_row($account) {
|
||||
$form['#account'] = $account;
|
||||
|
||||
$form['id'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $account->id,
|
||||
);
|
||||
|
||||
$form['uid'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $account->uid,
|
||||
);
|
||||
|
||||
$form['screen_name'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $account->screen_name,
|
||||
);
|
||||
|
||||
$form['image'] = array(
|
||||
'#markup' => theme('image', array('path' => $account->profile_image_url)),
|
||||
);
|
||||
|
||||
$form['visible_name'] = array(
|
||||
'#markup' => l($account->screen_name, 'http://www.twitter.com/' . $account->screen_name),
|
||||
);
|
||||
|
||||
$form['description'] = array(
|
||||
'#markup' => filter_xss($account->description),
|
||||
);
|
||||
|
||||
$form['protected'] = array(
|
||||
'#markup' => empty($account->protected) ? t('No') : t('Yes'),
|
||||
);
|
||||
|
||||
// Here we use user_access('import own tweets') to check permission
|
||||
// instead of user_access('import own tweets', $account->uid)
|
||||
// because we allow roles with sufficient permission to overwrite
|
||||
// the user's import settings.
|
||||
if (variable_get('twitter_import', TRUE) && user_access('import own tweets')) {
|
||||
$form['import'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#default_value' => user_access('import own tweets') ? $account->import : '',
|
||||
);
|
||||
}
|
||||
|
||||
$form['delete'] = array(
|
||||
'#type' => 'checkbox',
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Please document this function.
|
||||
* @see http://drupal.org/node/1354
|
||||
*/
|
||||
function theme_twitter_account_list_form($variables) {
|
||||
$form = $variables['form'];
|
||||
|
||||
if (variable_get('twitter_import', TRUE) && user_access('import own tweets')) {
|
||||
$header = array('', t('Name'), t('Description'), t('Private'), t('Import'), t('Delete'));
|
||||
}
|
||||
else {
|
||||
$header = array('', t('Name'), t('Description'), t('Private'), t('Delete'));
|
||||
}
|
||||
|
||||
if (user_access('make twitter accounts global')) {
|
||||
$header[] = '';
|
||||
}
|
||||
|
||||
$rows = array();
|
||||
|
||||
foreach (element_children($form['accounts']) as $key) {
|
||||
$element = &$form['accounts'][$key];
|
||||
if (variable_get('twitter_import', TRUE) && user_access('import own tweets')) {
|
||||
$row = array(
|
||||
drupal_render($element['image']),
|
||||
drupal_render($element['id']) . drupal_render($element['screen_name']) . drupal_render($element['visible_name']),
|
||||
drupal_render($element['description']),
|
||||
drupal_render($element['protected']),
|
||||
drupal_render($element['import']),
|
||||
drupal_render($element['delete']),
|
||||
);
|
||||
}
|
||||
else {
|
||||
$row = array(
|
||||
drupal_render($element['image']),
|
||||
drupal_render($element['id']) . drupal_render($element['screen_name']) . drupal_render($element['visible_name']),
|
||||
drupal_render($element['description']),
|
||||
drupal_render($element['protected']),
|
||||
drupal_render($element['delete']),
|
||||
);
|
||||
}
|
||||
|
||||
if (user_access('make twitter accounts global')) {
|
||||
$label = ($element['#account']->is_global) ? t('remove global') : t('make global');
|
||||
$row[] = l($label, 'user/' . $element['#account']->uid . '/edit/twitter/global/' . $element['#account']->id);
|
||||
}
|
||||
|
||||
$rows[] = $row;
|
||||
}
|
||||
|
||||
$output = theme('table', array('header' => $header, 'rows' => $rows));
|
||||
$output .= drupal_render_children($form);
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Please document this function.
|
||||
* @see http://drupal.org/node/1354
|
||||
*/
|
||||
function twitter_account_list_form_submit($form, &$form_state) {
|
||||
$accounts = $form_state['values']['accounts'];
|
||||
foreach ($accounts as $account) {
|
||||
if (empty($account['delete'])) {
|
||||
twitter_account_save($account);
|
||||
drupal_set_message(t('The Twitter account settings were updated.'));
|
||||
}
|
||||
else {
|
||||
twitter_account_delete($account['id']);
|
||||
drupal_set_message(t('The Twitter account was deleted.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Please document this function.
|
||||
* @see http://drupal.org/node/1354
|
||||
*/
|
||||
function twitter_user_make_global($form, $form_state, $account, $twitter_uid) {
|
||||
module_load_include('inc', 'twitter');
|
||||
|
||||
$twitter_account = twitter_account_load($twitter_uid);
|
||||
|
||||
$form = array();
|
||||
|
||||
$form['uid'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $account->uid,
|
||||
);
|
||||
|
||||
$form['twitter_uid'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $twitter_uid,
|
||||
);
|
||||
|
||||
if ($twitter_account->is_global) {
|
||||
$text = t('Are you sure you want to remove %screen_name from the global accounts?', array('%screen_name' => $twitter_account->screen_name));
|
||||
$description = t('This means other users will no longer be allowed to post using this account.');
|
||||
}
|
||||
else {
|
||||
$text = t('Are you sure you want to allow other users to access the %screen_name account?', array('%screen_name' => $twitter_account->screen_name));
|
||||
$description = t('This will allow other users to post using this account.');
|
||||
}
|
||||
|
||||
return confirm_form($form, $text, 'user/' . $account->uid . '/edit/twitter', $description);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Please document this function.
|
||||
* @see http://drupal.org/node/1354
|
||||
*/
|
||||
function twitter_user_make_global_submit($form, &$form_state) {
|
||||
db_update('twitter_account')
|
||||
->expression('is_global', '(1 - is_global)')
|
||||
->condition('twitter_uid', $form_state['values']['twitter_uid'])
|
||||
->execute();
|
||||
|
||||
$form_state['redirect'] = 'user/' . $form_state['values']['uid'] . '/edit/twitter';
|
||||
}
|
||||
|
||||
/**
|
||||
* Form to add a Twitter account
|
||||
*
|
||||
* If OAuth is not enabled, a text field lets users to add their
|
||||
* Twitter screen name. If it is, a submit button redirects to
|
||||
* Twitter.com asking for authorisation.
|
||||
*/
|
||||
function twitter_account_form($form, $form_state, $account = NULL) {
|
||||
if (empty($account)) {
|
||||
global $user;
|
||||
$account = $user;
|
||||
}
|
||||
|
||||
$form['uid'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $account->uid,
|
||||
);
|
||||
|
||||
if (_twitter_use_oauth()) {
|
||||
$form['#validate'] = array('twitter_account_oauth_validate');
|
||||
}
|
||||
else {
|
||||
$form['screen_name'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#required' => TRUE,
|
||||
'#title' => t('Twitter user name'),
|
||||
);
|
||||
|
||||
$form['import'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Import statuses from this account'),
|
||||
'#default_value' => TRUE,
|
||||
'#access' => FALSE,
|
||||
);
|
||||
}
|
||||
|
||||
$form['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Add account'),
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_FORM_ID_submit()
|
||||
*
|
||||
* Loads Twitter account details and adds them to the user account
|
||||
*/
|
||||
function twitter_account_form_submit($form, &$form_state) {
|
||||
module_load_include('lib.php', 'twitter');
|
||||
module_load_include('inc', 'twitter');
|
||||
|
||||
$name = $form_state['values']['screen_name'];
|
||||
$twitter = new Twitter($name);
|
||||
$account = $twitter->users_show($name, false);
|
||||
twitter_account_save($account, TRUE, user_load($form_state['values']['uid']));
|
||||
}
|
||||
|
||||
/**
|
||||
* If OAuth is enabled, intercept submission of 'Add Account' form on
|
||||
* user/%/edit/twitter page and redirect to Twitter for auth.
|
||||
*/
|
||||
function twitter_account_oauth_validate($form, &$form_state) {
|
||||
module_load_include('lib.php', 'oauth_common');
|
||||
module_load_include('lib.php', 'twitter');
|
||||
|
||||
$key = variable_get('twitter_consumer_key', '');
|
||||
$secret = variable_get('twitter_consumer_secret', '');
|
||||
if ($key == '' || $secret == '') {
|
||||
form_set_error('', t('Please configure your Twitter consumer key and secret.'));
|
||||
}
|
||||
|
||||
$twitter = new TwitterOAuth($key, $secret);
|
||||
$token = $twitter->get_request_token();
|
||||
|
||||
$_SESSION['twitter_oauth']['account'] = user_load($form['uid']['#value']);
|
||||
$_SESSION['twitter_oauth']['token'] = $token;
|
||||
$_SESSION['twitter_oauth']['destination'] = $_GET['q'];
|
||||
drupal_goto($twitter->get_authorize_url($token));
|
||||
}
|
||||
|
||||
/**
|
||||
* @TODO This code should probably be reviewed.
|
||||
*
|
||||
* Wrapper to call drupal_form_submit() which wasn't required in D6.
|
||||
*/
|
||||
function twitter_oauth_callback() {
|
||||
$form_state['values']['oauth_token'] = $_GET['oauth_token'];
|
||||
drupal_form_submit('twitter_oauth_callback_form', $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Form builder function. In D6 this form was built in response to the
|
||||
* oauth return request from Twitter, and the setting of
|
||||
* $form['#post'] seems to have caused the form to be validated and
|
||||
* processed.
|
||||
*/
|
||||
function twitter_oauth_callback_form($form, &$form_state) {
|
||||
$form['#post']['oauth_token'] = $_GET['oauth_token'];
|
||||
$form['oauth_token'] = array(
|
||||
'#type' => 'hidden',
|
||||
'#default_value' => $_GET['oauth_token'],
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate results from Twitter OAuth return request.
|
||||
*/
|
||||
function twitter_oauth_callback_form_validate($form, &$form_state) {
|
||||
$key = variable_get('twitter_consumer_key', '');
|
||||
$secret = variable_get('twitter_consumer_secret', '');
|
||||
|
||||
if ($key == '' || $secret == '') {
|
||||
form_set_error('', t('Please configure your Twitter consumer key and secret.'));
|
||||
}
|
||||
|
||||
if (isset($_SESSION['twitter_oauth'])) {
|
||||
$form_state['twitter_oauth'] = $_SESSION['twitter_oauth'];
|
||||
unset($_SESSION['twitter_oauth']);
|
||||
}
|
||||
else {
|
||||
form_set_error('oauth_token', 'Invalid Twitter OAuth request');
|
||||
}
|
||||
|
||||
if (isset($form_state['twitter_oauth']['token'])) {
|
||||
$token = $form_state['twitter_oauth']['token'];
|
||||
if (!is_array($token) || !$key || !$secret) {
|
||||
form_set_error('oauth_token', t('Invalid Twitter OAuth request'));
|
||||
}
|
||||
if ($token['oauth_token'] != $form_state['values']['oauth_token']) {
|
||||
form_set_error('oauth_token', t('Invalid OAuth token.'));
|
||||
}
|
||||
}
|
||||
else {
|
||||
form_set_error('oauth_token', t('Invalid Twitter OAuth request'));
|
||||
}
|
||||
|
||||
module_load_include('lib.php', 'oauth_common');
|
||||
module_load_include('lib.php', 'twitter');
|
||||
module_load_include('inc', 'twitter');
|
||||
|
||||
if ($twitter = new TwitterOAuth($key, $secret, $token['oauth_token'], $token['oauth_token_secret'])) {
|
||||
if ($response = $twitter->get_access_token()) {
|
||||
$form_state['twitter_oauth']['response'] = $response;
|
||||
}
|
||||
else {
|
||||
form_set_error('oauth_token', t('Invalid Twitter OAuth request'));
|
||||
}
|
||||
}
|
||||
else {
|
||||
form_set_error('oauth_token', t('Invalid Twitter OAuth request'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a Twitter OAuth return request and store the account creds
|
||||
* in the DB. Redirects to user/%/edit/twitter
|
||||
*
|
||||
* @TODO Redirect better.
|
||||
*
|
||||
* I don't much like the use of drupal_goto() here as it might
|
||||
* interfere with other modules trying to piggyback on the form
|
||||
* submission, but setting $form['redirect'] was leaving us at the
|
||||
* twitter/oauth URL.
|
||||
*/
|
||||
function twitter_oauth_callback_form_submit(&$form, &$form_state) {
|
||||
$key = variable_get('twitter_consumer_key', '');
|
||||
$secret = variable_get('twitter_consumer_secret', '');
|
||||
$response = $form_state['twitter_oauth']['response'];
|
||||
|
||||
$twitter = new TwitterOAuth($key, $secret, $response['oauth_token'], $response['oauth_token_secret']);
|
||||
$twitter_account = $twitter->users_show($response['screen_name']);
|
||||
$twitter_account->set_auth($response);
|
||||
$account = $form_state['twitter_oauth']['account'];
|
||||
twitter_account_save($twitter_account, TRUE, $account);
|
||||
|
||||
$form['#programmed'] = FALSE;
|
||||
|
||||
$form_state['redirect'] = url('user/' . $account->uid . '/edit/twitter');
|
||||
// redirect isn't firing - because we're using drupal_submit_form()?
|
||||
// - so adding drupal_goto() here (but not liking it).
|
||||
drupal_goto('user/' . $account->uid . '/edit/twitter');
|
||||
}
|
357
sites/all/modules/twitter/twitter.views.inc
Normal file
357
sites/all/modules/twitter/twitter.views.inc
Normal file
@@ -0,0 +1,357 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Provide views data and handlers for twitter.module
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup views_twitter_module twitter.module handlers
|
||||
*
|
||||
* Includes the ability to create views of just the twitter table.
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Implements hook_views_data().
|
||||
*/
|
||||
function twitter_views_data() {
|
||||
// Basic table information.
|
||||
|
||||
$data['twitter']['table']['group'] = t('Twitter');
|
||||
|
||||
// Advertise this table as a possible base table
|
||||
$data['twitter']['table']['base'] = array(
|
||||
'field' => 'twitter_id',
|
||||
'title' => t('Twitter message'),
|
||||
'help' => t('Twitter status messages.'),
|
||||
'weight' => 10,
|
||||
);
|
||||
|
||||
// Tweet ID
|
||||
$data['twitter']['twitter_id'] = array(
|
||||
'title' => t('Twitter status message ID'),
|
||||
'help' => t('The ID of the Twitter status message.'),
|
||||
'field' => array(
|
||||
'handler' => 'views_handler_field',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_filter_numeric',
|
||||
),
|
||||
'sort' => array(
|
||||
'handler' => 'views_handler_sort',
|
||||
),
|
||||
'argument' => array(
|
||||
'handler' => 'views_handler_argument_string',
|
||||
),
|
||||
);
|
||||
|
||||
// Twitter reply-to-status id
|
||||
$data['twitter']['in_reply_to_status_id'] = array(
|
||||
'title' => t('In reply to status ID'),
|
||||
'help' => t('The ID of the Twitter status this message is replying to.'),
|
||||
'field' => array(
|
||||
'handler' => 'views_handler_field',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_filter_numeric',
|
||||
'allow empty' => TRUE,
|
||||
),
|
||||
'sort' => array(
|
||||
'handler' => 'views_handler_sort',
|
||||
),
|
||||
);
|
||||
|
||||
// Twitter reply-to-status screen name
|
||||
$data['twitter']['in_reply_to_screen_name'] = array(
|
||||
'title' => t('In reply to user name'),
|
||||
'help' => t('The login account of the Twitter user this message is replying to.'),
|
||||
'field' => array(
|
||||
'handler' => 'views_handler_field',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_filter_string',
|
||||
'allow empty' => TRUE,
|
||||
),
|
||||
'sort' => array(
|
||||
'handler' => 'views_handler_sort',
|
||||
),
|
||||
'argument' => array(
|
||||
'handler' => 'views_handler_argument_string',
|
||||
),
|
||||
);
|
||||
|
||||
// Twitter screen name
|
||||
$data['twitter']['screen_name'] = array(
|
||||
'title' => t('Login name'),
|
||||
'help' => t('The login account of the Twitter user.'),
|
||||
'field' => array(
|
||||
'handler' => 'views_handler_field',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_filter_string',
|
||||
),
|
||||
'sort' => array(
|
||||
'handler' => 'views_handler_sort',
|
||||
),
|
||||
'argument' => array(
|
||||
'handler' => 'views_handler_argument_string',
|
||||
),
|
||||
);
|
||||
|
||||
// Twitter message timestamp
|
||||
$data['twitter']['created_time'] = array(
|
||||
'title' => t('Created time'),
|
||||
'help' => t('The time the Twitter message was posted.'),
|
||||
'field' => array(
|
||||
'handler' => 'views_handler_field_date',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
'sort' => array(
|
||||
'handler' => 'views_handler_sort',
|
||||
),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_filter_date',
|
||||
),
|
||||
);
|
||||
|
||||
// Twitter text
|
||||
$data['twitter']['text'] = array(
|
||||
'title' => t('Message text'),
|
||||
'help' => t('The text of the Twitter message.'),
|
||||
'field' => array(
|
||||
'handler' => 'twitter_views_handler_field_xss',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_filter_string',
|
||||
),
|
||||
);
|
||||
|
||||
// Twitter source
|
||||
$data['twitter']['source'] = array(
|
||||
'title' => t('Source'),
|
||||
'help' => t('The name of the application that posted the Twitter message.'),
|
||||
'field' => array(
|
||||
'handler' => 'views_handler_field_xss',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_filter_string',
|
||||
),
|
||||
'sort' => array(
|
||||
'handler' => 'views_handler_sort',
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
$data['twitter_account']['table']['group'] = t('Twitter');
|
||||
|
||||
$data['twitter_account']['table']['join'] = array(
|
||||
'twitter' => array(
|
||||
'left_field' => 'screen_name',
|
||||
'field' => 'screen_name',
|
||||
),
|
||||
'users' => array(
|
||||
'left_field' => 'uid',
|
||||
'field' => 'uid',
|
||||
// 'left_table' => 'twitter_user',
|
||||
),
|
||||
);
|
||||
|
||||
// Twitter screen name
|
||||
$data['twitter_account']['screen_name'] = array(
|
||||
'title' => t('Login name'),
|
||||
'help' => t('The login account of the Twitter user.'),
|
||||
'field' => array(
|
||||
'handler' => 'views_handler_field',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_filter_string',
|
||||
),
|
||||
'sort' => array(
|
||||
'handler' => 'views_handler_sort',
|
||||
),
|
||||
'argument' => array(
|
||||
'handler' => 'views_handler_argument_string',
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
// Twitter account full name
|
||||
$data['twitter_account']['name'] = array(
|
||||
'title' => t('Full name'),
|
||||
'help' => t('The full name Twitter account user.'),
|
||||
'field' => array(
|
||||
'handler' => 'views_handler_field',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_filter_string',
|
||||
),
|
||||
'sort' => array(
|
||||
'handler' => 'views_handler_sort',
|
||||
),
|
||||
'argument' => array(
|
||||
'handler' => 'views_handler_argument_string',
|
||||
),
|
||||
);
|
||||
|
||||
// Twitter account description
|
||||
$data['twitter_account']['description'] = array(
|
||||
'title' => t('Description'),
|
||||
'help' => t('The description of the Twitter account.'),
|
||||
'field' => array(
|
||||
'handler' => 'views_handler_field',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_field_xss',
|
||||
),
|
||||
'sort' => array(
|
||||
'handler' => 'views_handler_sort',
|
||||
),
|
||||
);
|
||||
|
||||
// Twitter account location
|
||||
$data['twitter_account']['location'] = array(
|
||||
'title' => t('Location'),
|
||||
'help' => t('The location of the Twitter account.'),
|
||||
'field' => array(
|
||||
'handler' => 'views_handler_field',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_field_xss',
|
||||
),
|
||||
'sort' => array(
|
||||
'handler' => 'views_handler_sort',
|
||||
),
|
||||
);
|
||||
|
||||
// Twitter account description
|
||||
$data['twitter_account']['followers_count'] = array(
|
||||
'title' => t('Followers'),
|
||||
'help' => t('The number of users following this Twitter account.'),
|
||||
'field' => array(
|
||||
'handler' => 'views_handler_field_numeric',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_filter_numeric',
|
||||
),
|
||||
'sort' => array(
|
||||
'handler' => 'views_handler_sort',
|
||||
),
|
||||
);
|
||||
|
||||
// Twitter account profile image
|
||||
$data['twitter_account']['profile_image_url'] = array(
|
||||
'title' => t('Profile image'),
|
||||
'help' => t('The image used by the Twitter account.'),
|
||||
'field' => array(
|
||||
'handler' => 'twitter_views_handler_field_profile_image',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
);
|
||||
|
||||
// Twitter account url
|
||||
$data['twitter_account']['url'] = array(
|
||||
'title' => t('URL'),
|
||||
'help' => t('The URL given by the Twitter account user.'),
|
||||
'field' => array(
|
||||
'handler' => 'views_handler_field_url',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_filter_string',
|
||||
),
|
||||
'sort' => array(
|
||||
'handler' => 'views_handler_sort',
|
||||
),
|
||||
);
|
||||
|
||||
// Twitter account protected
|
||||
$data['twitter_account']['protected'] = array(
|
||||
'title' => t('Protected status'),
|
||||
'help' => t('Whether posts from this Twitter account should be visible to the general public.'),
|
||||
'field' => array(
|
||||
'handler' => 'views_handler_field_boolean',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_filter_boolean_operator',
|
||||
),
|
||||
'sort' => array(
|
||||
'handler' => 'views_handler_sort',
|
||||
),
|
||||
);
|
||||
|
||||
// Twitter message timestamp
|
||||
$data['twitter_account']['last_refresh'] = array(
|
||||
'title' => t('Last refresh'),
|
||||
'help' => t('The time the Twitter account statuses were retrieved.'),
|
||||
'field' => array(
|
||||
'handler' => 'views_handler_field_date',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
'sort' => array(
|
||||
'handler' => 'views_handler_sort',
|
||||
),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_filter_date',
|
||||
),
|
||||
);
|
||||
|
||||
// Twitter account description
|
||||
$data['twitter_account']['uid'] = array(
|
||||
'title' => t('User ID'),
|
||||
'help' => t('The UID of the Twitter account.'),
|
||||
);
|
||||
// Twitter account protected
|
||||
$data['twitter_account']['import'] = array(
|
||||
'title' => t('Import status'),
|
||||
'help' => t('Whether posts from this Twitter account should be imported automatically.'),
|
||||
'field' => array(
|
||||
'handler' => 'views_handler_field_boolean',
|
||||
'click sortable' => TRUE,
|
||||
),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_filter_boolean_operator',
|
||||
),
|
||||
'sort' => array(
|
||||
'handler' => 'views_handler_sort',
|
||||
),
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @todo Please document this function.
|
||||
* @see http://drupal.org/node/1354
|
||||
*/
|
||||
function twitter_views_data_alter(&$data) {
|
||||
$data['users']['table']['join']['twitter'] = array(
|
||||
'left_table' => 'twitter_account',
|
||||
'left_field' => 'uid',
|
||||
'field' => 'uid',
|
||||
);
|
||||
$data['users']['table']['join']['twitter_account'] = array(
|
||||
// 'left_table' => 'twitter_user',
|
||||
'left_field' => 'uid',
|
||||
'field' => 'uid',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
193
sites/all/modules/twitter/twitter.views_default.inc
Normal file
193
sites/all/modules/twitter/twitter.views_default.inc
Normal file
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
function twitter_views_default_views() {
|
||||
$view = new view;
|
||||
$view->name = 'tweets';
|
||||
$view->description = 'Displays Twitter.com status messages for users who have associated Twitter accounts.';
|
||||
$view->tag = '';
|
||||
$view->view_php = '';
|
||||
$view->base_table = 'twitter';
|
||||
$view->is_cacheable = '0';
|
||||
$view->api_version = 2;
|
||||
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
|
||||
$handler = $view->new_display('default', 'Tweets', 'default');
|
||||
$handler->override_option('fields', array(
|
||||
'profile_image_url' => array(
|
||||
'label' => '',
|
||||
'exclude' => 0,
|
||||
'id' => 'profile_image_url',
|
||||
'table' => 'twitter_account',
|
||||
'field' => 'profile_image_url',
|
||||
'relationship' => 'none',
|
||||
),
|
||||
'text' => array(
|
||||
'label' => '',
|
||||
'exclude' => 0,
|
||||
'id' => 'text',
|
||||
'table' => 'twitter',
|
||||
'field' => 'text',
|
||||
'relationship' => 'none',
|
||||
),
|
||||
'created_time' => array(
|
||||
'label' => '',
|
||||
'date_format' => 'time ago',
|
||||
'custom_date_format' => '',
|
||||
'exclude' => 0,
|
||||
'id' => 'created_time',
|
||||
'table' => 'twitter',
|
||||
'field' => 'created_time',
|
||||
'relationship' => 'none',
|
||||
),
|
||||
));
|
||||
$handler->override_option('sorts', array(
|
||||
'created_time' => array(
|
||||
'order' => 'DESC',
|
||||
'id' => 'created_time',
|
||||
'table' => 'twitter',
|
||||
'field' => 'created_time',
|
||||
'relationship' => 'none',
|
||||
),
|
||||
));
|
||||
$handler->override_option('arguments', array(
|
||||
'uid' => array(
|
||||
'default_action' => 'default',
|
||||
'style_plugin' => 'default_summary',
|
||||
'style_options' => array(),
|
||||
'wildcard' => 'all',
|
||||
'wildcard_substitution' => 'All author',
|
||||
'title' => '%1\'s tweets',
|
||||
'default_argument_type' => 'user',
|
||||
'default_argument' => '',
|
||||
'validate_type' => 'php',
|
||||
'validate_options' => array(
|
||||
'code' => '$uid = arg(1);
|
||||
if (!empty($uid)) {
|
||||
$account = user_load($uid);
|
||||
$twitter_accounts = twitter_twitter_accounts($account);
|
||||
if(count($twitter_accounts)) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}',
|
||||
),
|
||||
'validate_fail' => 'not found',
|
||||
'break_phrase' => 0,
|
||||
'not' => 0,
|
||||
'id' => 'uid',
|
||||
'table' => 'users',
|
||||
'field' => 'uid',
|
||||
'relationship' => 'none',
|
||||
'default_argument_user' => 1,
|
||||
'default_argument_fixed' => '',
|
||||
'default_argument_php' => '',
|
||||
'validate_argument_node_type' => array(
|
||||
'poll' => 0,
|
||||
'page' => 0,
|
||||
'review' => 0,
|
||||
'story' => 0,
|
||||
),
|
||||
'validate_argument_node_access' => 0,
|
||||
'validate_argument_nid_type' => 'nid',
|
||||
'validate_argument_vocabulary' => array(),
|
||||
'validate_argument_type' => 'tid',
|
||||
'validate_argument_php' => '',
|
||||
),
|
||||
));
|
||||
$handler->override_option('filters', array(
|
||||
'protected' => array(
|
||||
'operator' => '=',
|
||||
'value' => 0,
|
||||
'group' => '0',
|
||||
'exposed' => FALSE,
|
||||
'expose' => array(
|
||||
'operator' => FALSE,
|
||||
'label' => '',
|
||||
),
|
||||
'id' => 'protected',
|
||||
'table' => 'twitter_account',
|
||||
'field' => 'protected',
|
||||
'relationship' => 'none',
|
||||
),
|
||||
));
|
||||
$handler->override_option('access', array(
|
||||
'type' => 'none',
|
||||
'role' => array(),
|
||||
'perm' => '',
|
||||
));
|
||||
$handler->override_option('use_pager', 'mini');
|
||||
$handler->override_option('style_plugin', 'table');
|
||||
$handler->override_option('style_options', array(
|
||||
'grouping' => '',
|
||||
'override' => 1,
|
||||
'sticky' => 0,
|
||||
'order' => 'asc',
|
||||
'columns' => array(
|
||||
'profile_image_url' => 'profile_image_url',
|
||||
'text' => 'text',
|
||||
'created_time' => 'text',
|
||||
),
|
||||
'info' => array(
|
||||
'profile_image_url' => array(
|
||||
'sortable' => 0,
|
||||
'separator' => '',
|
||||
),
|
||||
'text' => array(
|
||||
'sortable' => 0,
|
||||
'separator' => ' — ',
|
||||
),
|
||||
'created_time' => array(
|
||||
'sortable' => 0,
|
||||
'separator' => '',
|
||||
),
|
||||
),
|
||||
'default' => '-1',
|
||||
));
|
||||
$handler = $view->new_display('page', 'Page', 'page');
|
||||
$handler->override_option('path', 'user/%/tweets');
|
||||
$handler->override_option('menu', array(
|
||||
'type' => 'tab',
|
||||
'title' => 'Twitter',
|
||||
'weight' => '1',
|
||||
));
|
||||
$handler->override_option('tab_options', array(
|
||||
'type' => 'none',
|
||||
'title' => '',
|
||||
'weight' => 0,
|
||||
));
|
||||
$handler = $view->new_display('block', 'Block', 'block');
|
||||
$handler->override_option('fields', array(
|
||||
'text' => array(
|
||||
'label' => '',
|
||||
'exclude' => 0,
|
||||
'id' => 'text',
|
||||
'table' => 'twitter',
|
||||
'field' => 'text',
|
||||
'relationship' => 'none',
|
||||
),
|
||||
'created_time' => array(
|
||||
'label' => '',
|
||||
'date_format' => 'time ago',
|
||||
'custom_date_format' => '',
|
||||
'exclude' => 0,
|
||||
'id' => 'created_time',
|
||||
'table' => 'twitter',
|
||||
'field' => 'created_time',
|
||||
'relationship' => 'none',
|
||||
),
|
||||
));
|
||||
$handler->override_option('items_per_page', 5);
|
||||
$handler->override_option('use_more', 1);
|
||||
$handler->override_option('style_plugin', 'list');
|
||||
$handler->override_option('row_options', array(
|
||||
'inline' => array(
|
||||
'text' => 'text',
|
||||
'created_time' => 'created_time',
|
||||
),
|
||||
'separator' => ' — ',
|
||||
));
|
||||
$handler->override_option('block_description', 'User Tweets');
|
||||
|
||||
return array('tweets' => $view);
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
name = Twitter actions
|
||||
description = Exposes Drupal actions to send Twitter messages.
|
||||
core = 7.x
|
||||
dependencies[] = twitter
|
||||
dependencies[] = oauth_common
|
||||
|
||||
; Information added by drupal.org packaging script on 2011-12-03
|
||||
version = "7.x-3.0-beta4"
|
||||
core = "7.x"
|
||||
project = "twitter"
|
||||
datestamp = "1322940643"
|
||||
|
188
sites/all/modules/twitter/twitter_actions/twitter_actions.module
Normal file
188
sites/all/modules/twitter/twitter_actions/twitter_actions.module
Normal file
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Exposes Drupal actions for sending Twitter messages.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_action_info().
|
||||
*/
|
||||
function twitter_actions_action_info() {
|
||||
return array(
|
||||
'twitter_actions_set_status_action' => array(
|
||||
'type' => 'system',
|
||||
'label' => t('Post a message to Twitter'),
|
||||
'configurable' => TRUE,
|
||||
'triggers' => array(
|
||||
'node_view',
|
||||
'node_insert',
|
||||
'node_update',
|
||||
'node_delete',
|
||||
'comment_view',
|
||||
'comment_insert',
|
||||
'comment_update',
|
||||
'comment_delete',
|
||||
'user_view',
|
||||
'user_insert',
|
||||
'user_update',
|
||||
'user_delete',
|
||||
'user_login',
|
||||
'cron',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a form definition so the Twitter action can be configured.
|
||||
*
|
||||
* @param $context
|
||||
* Default values (if we are editing an existing action instance).
|
||||
* @return
|
||||
* Form definition.
|
||||
*/
|
||||
function twitter_actions_set_status_action_form($context) {
|
||||
$options = array();
|
||||
$results = db_query("SELECT screen_name FROM {twitter_account}");
|
||||
foreach ($results as $result) {
|
||||
$options[$result->screen_name] = $result->screen_name;
|
||||
}
|
||||
// Set default values for form.
|
||||
$form['screen_name'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Twitter account name'),
|
||||
'#options' => $options,
|
||||
'#default_value' => isset($context['screen_name']) ? $context['screen_name'] : '',
|
||||
'#required' => TRUE,
|
||||
);
|
||||
|
||||
if (!count($options)) {
|
||||
$form['screen_name']['#description'] = t('You first need to add a Twitter account to one of ' .
|
||||
'your users with rights for posting to Twitter.');
|
||||
}
|
||||
|
||||
$form['message'] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => t('Message'),
|
||||
'#default_value' => isset($context['message']) ? $context['message'] : '',
|
||||
'#cols' => '80',
|
||||
'#rows' => '3',
|
||||
'#description' => t('The message that should be sent. You may include the following variables: ' .
|
||||
'%site_name, %username, %node_url, %node_type, %title, %summary, %body, ' .
|
||||
'%tinyurl. Not all variables will be available in all contexts.'),
|
||||
'#required' => TRUE,
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if Oauth module has been setup and also checks the Twitter
|
||||
* authentication against the provided screen name.
|
||||
*/
|
||||
function twitter_actions_set_status_action_validate($form, $form_state) {
|
||||
if (!_twitter_use_oauth()) {
|
||||
form_set_error('screen_name', t('Oauth has not been setup yet. Please go to !link and follow steps.',
|
||||
array('!link' => l(t('Twitter settings'), 'admin/settings/twitter'))));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Submits the form and sets the twitter account pulling the data from the
|
||||
* twitter_account table.
|
||||
*/
|
||||
function twitter_actions_set_status_action_submit($form, $form_state) {
|
||||
$form_values = $form_state['values'];
|
||||
$twitter_uid = db_query("SELECT twitter_uid FROM {twitter_account} WHERE screen_name = :screen_name", array(':screen_name' => $form_values['screen_name']))->fetchField();
|
||||
// Process the HTML form to store configuration. The keyed array that
|
||||
// we return will be serialized to the database.
|
||||
$params = array(
|
||||
'twitter_uid' => $twitter_uid,
|
||||
'screen_name' => $form_values['screen_name'],
|
||||
'message' => $form_values['message'],
|
||||
);
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of a configurable Twitter actions.
|
||||
* @todo Implementation for language negotiation for the body and sumary. Also
|
||||
* need implementation for bodies with multiple values. Right now it is hard
|
||||
* coded and it will only get body and summary for 'und' language and only
|
||||
* the first value of the body field.
|
||||
* If the final message is over 140 chars, there is no feedback to the user.
|
||||
*/
|
||||
function twitter_actions_set_status_action($object, $context) {
|
||||
global $user;
|
||||
$variables['%site_name'] = variable_get('site_name', 'Drupal');
|
||||
// Seting variables array depending on action's group
|
||||
switch ($context['group']) {
|
||||
case 'node':
|
||||
$node = $context['node'];
|
||||
if (isset($node)) {
|
||||
$variables = array_merge($variables, array(
|
||||
'%uid' => $node->uid,
|
||||
'%username' => $node->name,
|
||||
'%node_url' => url('node/' . $node->nid, array('absolute' => TRUE)),
|
||||
'%node_type' => node_type_get_name($node),
|
||||
'%title' => $node->title,
|
||||
'%summary' => isset($node->body['und'][0]['value']) ? $node->body['und'][0]['summary'] : '',
|
||||
'%body' => isset($node->body['und'][0]['value']) ? $node->body['und'][0]['value'] : '',
|
||||
)
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'comment':
|
||||
$node = node_load($context['comment']->nid);
|
||||
if (isset($node)) {
|
||||
$variables = array_merge($variables, array(
|
||||
'%uid' => $context['comment']->uid,
|
||||
'%username' => $context['comment']->name,
|
||||
'%node_url' => url('node/' . $node->nid, array('absolute' => TRUE)),
|
||||
'%node_type' => node_type_get_name($node),
|
||||
'%title' => $node->title,
|
||||
'%summary' => isset($node->body['und'][0]['value']) ? $node->body['und'][0]['summary'] : '',
|
||||
'%body' => isset($node->body['und'][0]['value']) ? $node->body['und'][0]['value'] : '',
|
||||
)
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'user':
|
||||
$variables['%username'] = $context['user']->name;
|
||||
break;
|
||||
|
||||
case 'cron':
|
||||
break;
|
||||
|
||||
default:
|
||||
// We are being called directly.
|
||||
$node = $object;
|
||||
if (isset($node) && is_object($node)) {
|
||||
$variables = array_merge($variables, array(
|
||||
'%uid' => $node->uid,
|
||||
'%username' => $node->name,
|
||||
'%node_url' => url('node/' . $node->nid, array('absolute' => TRUE)),
|
||||
'%node_type' => node_type_get_name($node),
|
||||
'%title' => $node->title,
|
||||
'%summary' => isset($node->body['und'][0]['value']) ? $node->body['und'][0]['summary'] : '',
|
||||
'%body' => isset($node->body['und'][0]['value']) ? $node->body['und'][0]['value'] : '',
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Only make a tinyurl if it was asked for.
|
||||
if (strstr($context['message'], '%tinyurl') !== FALSE) {
|
||||
$variables = array_merge($variables, array(
|
||||
'%tinyurl' => twitter_shorten_url(url('node/' . $node->nid, array('absolute' => TRUE))),
|
||||
));
|
||||
}
|
||||
|
||||
$message = strtr($context['message'], $variables);
|
||||
module_load_include('inc', 'twitter');
|
||||
$twitter_account = twitter_account_load($context['twitter_uid']);
|
||||
twitter_set_status($twitter_account, $message);
|
||||
}
|
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Provide better intergration into the rules module
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_rules_action_info() on behalf of the twitter module.
|
||||
*/
|
||||
function twitter_actions_rules_action_info() {
|
||||
return array(
|
||||
'rules_core_twitter_actions_set_status_action' => array(
|
||||
'label' => t('Post a message to Twitter'),
|
||||
'group' => t('Twitter'),
|
||||
'parameter' => array(
|
||||
'message' => array(
|
||||
'type' => 'text',
|
||||
'label' => t('Message'),
|
||||
'description' => t("The content of the tweet."),
|
||||
),
|
||||
'sender' => array(
|
||||
'type' => 'user',
|
||||
'label' => t('Sender'),
|
||||
'description' => t("User whose Twitter account will be used."),
|
||||
),
|
||||
),
|
||||
'base' => 'twitter_actions_set_status',
|
||||
'access callback' => 'rules_twitter_actions_access_callback',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches Twitter account info and submits with the message to the Twitter API
|
||||
*
|
||||
* @param $message
|
||||
* The message to post
|
||||
* @param $sender
|
||||
* The Drupal user that has a Twitter account
|
||||
*/
|
||||
function twitter_actions_set_status($message, $sender) {
|
||||
if ($twitter_uid = db_query("SELECT twitter_uid FROM {twitter_account} WHERE uid = :uid", array(':uid' => $sender->uid))->fetchField()) {
|
||||
module_load_include('inc', 'twitter');
|
||||
$twitter_account = twitter_account_load($twitter_uid);
|
||||
twitter_set_status($twitter_account, $message);
|
||||
}
|
||||
else {
|
||||
watchdog('twitter', 'Twitter authentication failed. Please check your account name and try again.', array(), WATCHDOG_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_rules_condition_info().
|
||||
*/
|
||||
function twitter_actions_rules_condition_info() {
|
||||
$defaults = array(
|
||||
'group' => t('Twitter'),
|
||||
'parameter' => array(
|
||||
'user' => array(
|
||||
'type' => 'user',
|
||||
'label' => t('User'),
|
||||
'description' => t('The user to be checked for.'),
|
||||
),
|
||||
),
|
||||
'named parameter' => TRUE,
|
||||
'access callback' => 'rules_twitter_actions_access_callback',
|
||||
);
|
||||
$items['rules_core_twitter_conditions_user_has_linked'] = $defaults + array(
|
||||
'label' => t('User has linked Twitter account'),
|
||||
'help' => t('Evaluates to TRUE in case there is a record in the twitter_account for the provided user.'),
|
||||
'base' => 'twitter_actions_has_linked',
|
||||
);
|
||||
|
||||
$items['rules_core_twitter_conditions_text_is_under_140'] = array(
|
||||
'group' => t('Twitter'),
|
||||
'named parameter' => TRUE,
|
||||
'parameter' => array(
|
||||
'text' => array(
|
||||
'type' => 'text',
|
||||
'label' => t('Text to check'),
|
||||
),
|
||||
),
|
||||
'label' => t('Text is under 140 characters'),
|
||||
'help' => t('Returns TRUE if the length of the text is 140 or less.'),
|
||||
'base' => 'twitter_actions_less_140',
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* The callback function for the Rules condition
|
||||
* @param $element
|
||||
* $element['user']: The user to be checked for.
|
||||
* @return
|
||||
* TRUE if the user has linked his/her Twitter account.
|
||||
*/
|
||||
function twitter_actions_has_linked($element) {
|
||||
return db_query("SELECT twitter_uid FROM {twitter_account} WHERE uid = :uid", array(':uid' => $element['user']->uid))->fetchField() ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* The callback function for the Rules condition
|
||||
* @param $element
|
||||
* $element['user']: The user to be checked for.
|
||||
* @return
|
||||
* TRUE if the user has linked his/her Twitter account.
|
||||
*/
|
||||
function twitter_actions_less_140($element) {
|
||||
return strlen($element['text']) < 141;
|
||||
}
|
||||
|
||||
/**
|
||||
* The callback function to access the condition
|
||||
*/
|
||||
function rules_twitter_actions_access_callback($type, $name) {
|
||||
return user_access('add twitter accounts');
|
||||
}
|
12
sites/all/modules/twitter/twitter_post/twitter_post.info
Normal file
12
sites/all/modules/twitter/twitter_post/twitter_post.info
Normal file
@@ -0,0 +1,12 @@
|
||||
name = Twitter Post
|
||||
description = Enables posting to twitter
|
||||
core = 7.x
|
||||
dependencies[] = twitter
|
||||
dependencies[] = oauth_common
|
||||
|
||||
; Information added by drupal.org packaging script on 2011-12-03
|
||||
version = "7.x-3.0-beta4"
|
||||
core = "7.x"
|
||||
project = "twitter"
|
||||
datestamp = "1322940643"
|
||||
|
33
sites/all/modules/twitter/twitter_post/twitter_post.js
Normal file
33
sites/all/modules/twitter/twitter_post/twitter_post.js
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Attach handlers to toggle the twitter message field and inform the number
|
||||
* of characters remaining to achieve the max length
|
||||
*/
|
||||
(function ($) {
|
||||
Drupal.behaviors.twitter_post = {
|
||||
attach: function (context, settings) {
|
||||
$("#twitter-textfield", context).keyup(function() {
|
||||
var charsLeft = (140 - $(this).val().length);
|
||||
var descDiv = $(this).next();
|
||||
$(descDiv).html("<strong>" + charsLeft + "</strong> characters remaining");
|
||||
if (charsLeft < 0) {
|
||||
$(descDiv).addClass("negative");
|
||||
} else {
|
||||
$(descDiv).removeClass("negative");
|
||||
}
|
||||
});
|
||||
|
||||
if (!$("#twitter-toggle").attr("checked")) {
|
||||
$(".form-item-twitter-status").hide();
|
||||
}
|
||||
|
||||
$("#twitter-toggle").bind("click", function() {
|
||||
if ($("#twitter-toggle").attr("checked")) {
|
||||
$(".form-item-twitter-status").show();
|
||||
}
|
||||
else {
|
||||
$(".form-item-twitter-status").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}(jQuery));
|
164
sites/all/modules/twitter/twitter_post/twitter_post.module
Normal file
164
sites/all/modules/twitter/twitter_post/twitter_post.module
Normal file
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Main hooks for twitter post module
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function twitter_post_menu() {
|
||||
$items['admin/config/services/twitter/post'] = array(
|
||||
'title' => 'Post',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('twitter_post_admin_settings'),
|
||||
'access arguments' => array('administer site configuration'),
|
||||
'file' => 'twitter_post.pages.inc',
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'weight' => 3,
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_permission().
|
||||
*/
|
||||
function twitter_post_permission() {
|
||||
return array(
|
||||
'post to twitter' => array(
|
||||
'title' => t('Post a message to Twitter'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_form_alter().
|
||||
*/
|
||||
function twitter_post_form_alter(&$form, $form_state, $form_id) {
|
||||
// Alter any node forms.
|
||||
if (isset($form['#node']) && $form['#node']->type . '_node_form' == $form_id) {
|
||||
// If we haven't enabled Twitter posting on this node type, nothing to do
|
||||
// here.
|
||||
$type = $form['#node']->type;
|
||||
$allowed_types = variable_get('twitter_post_types', array('story' => 'story', 'blog' => 'blog'));
|
||||
if (empty($allowed_types[$type])) {
|
||||
return;
|
||||
}
|
||||
|
||||
module_load_include('inc', 'twitter');
|
||||
|
||||
$twitter_form = twitter_post_form();
|
||||
if (!$twitter_form) {
|
||||
return;
|
||||
}
|
||||
$form['twitter'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Post to twitter.com'),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => FALSE,
|
||||
'#tree' => TRUE,
|
||||
);
|
||||
$form['twitter']['post'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Announce this post on Twitter'),
|
||||
'#default_value' => (empty($form['nid']['#value'])),
|
||||
'#id' => 'twitter-toggle',
|
||||
);
|
||||
$form['twitter'] += $twitter_form;
|
||||
$form['twitter']['status']['#default_value'] = variable_get('twitter_post_default_format', 'New post: !title !tinyurl');
|
||||
$form['twitter']['status']['#description'] = t('The given text will be posted to twitter.com. You can use !url, !url-alias, !tinyurl, !title and !user as replacement text.');
|
||||
$form['twitter']['status']['#maxlength'] = 150;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_node_insert().
|
||||
*
|
||||
* Intercepts newly published nodes and posts noticed to Twitter.
|
||||
*/
|
||||
function twitter_post_node_insert($node) {
|
||||
if (!empty($node->status) && !empty($node->twitter) && !empty($node->twitter['post'])) {
|
||||
module_load_include('inc', 'twitter');
|
||||
|
||||
$twitter_account = twitter_account_load($node->twitter['account']);
|
||||
$replacements = array(
|
||||
'!title' => $node->title,
|
||||
'!url' => url('node/' . $node->nid, array('absolute' => TRUE, 'alias' => TRUE)),
|
||||
'!url-alias' => url('node/' . $node->nid, array('absolute' => TRUE)),
|
||||
'!user' => $node->name,
|
||||
);
|
||||
|
||||
// Only generate the shortened URL if it's going to be used. No sense
|
||||
// burning through TinyURLs without a good reason.
|
||||
if (strstr($node->twitter['status'], '!tinyurl') !== FALSE) {
|
||||
$replacements['!tinyurl'] = twitter_shorten_url(url('node/' . $node->nid, array('absolute' => TRUE)));
|
||||
}
|
||||
|
||||
$status = strtr($node->twitter['status'], $replacements);
|
||||
try {
|
||||
$result = twitter_set_status($twitter_account, $status);
|
||||
drupal_set_message(t('Successfully posted to Twitter'));
|
||||
}
|
||||
catch (TwitterException $e) {
|
||||
drupal_set_message(t('An error occurred when posting to twitter: %code %error',
|
||||
array('%code' => $result->code, '%error' => $result->error)), 'warning');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_node_update().
|
||||
*/
|
||||
function twitter_post_node_update($node) {
|
||||
twitter_post_node_insert($node);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate a twitter posting form for the given user.
|
||||
*
|
||||
* @param $account
|
||||
* A Drupal user object.
|
||||
*/
|
||||
function twitter_post_form($account = NULL) {
|
||||
drupal_add_js(drupal_get_path('module', 'twitter_post') . '/twitter_post.js');
|
||||
|
||||
if (empty($account)) {
|
||||
$account = user_load($GLOBALS['user']->uid);
|
||||
}
|
||||
|
||||
if (!user_access('post to twitter', $account)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$options = array();
|
||||
foreach ($account->twitter_accounts as $twitter_account) {
|
||||
$options[$twitter_account->id] = $twitter_account->screen_name;
|
||||
}
|
||||
|
||||
if (count($options)) {
|
||||
$form = array();
|
||||
$form['status'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#id' => 'twitter-textfield',
|
||||
);
|
||||
|
||||
if (count($options) > 1) {
|
||||
$form['account'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Account'),
|
||||
'#options' => $options,
|
||||
'#id' => 'twitter-account',
|
||||
);
|
||||
}
|
||||
else {
|
||||
$form['account'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => array_pop(array_keys($options)),
|
||||
);
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Settings form callback
|
||||
*/
|
||||
function twitter_post_admin_settings($form, &$form_state) {
|
||||
$form['twitter_post_types'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => t('Node types'),
|
||||
'#options' => node_type_get_names(),
|
||||
'#default_value' => variable_get('twitter_post_types', array('story' => 'story', 'blog' => 'blog')),
|
||||
);
|
||||
|
||||
$form['twitter_post_default_format'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Default format string'),
|
||||
'#maxlength' => 140,
|
||||
'#description' => t('The given text will be posted to twitter.com. You can use !url, !url-alias, !tinyurl, !title, and !user as replacement text.'),
|
||||
'#default_value' => variable_get('twitter_post_default_format', 'New post: !title !tinyurl'),
|
||||
);
|
||||
|
||||
return system_settings_form($form);
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
13
sites/all/modules/twitter/twitter_signin/twitter_signin.info
Normal file
13
sites/all/modules/twitter/twitter_signin/twitter_signin.info
Normal file
@@ -0,0 +1,13 @@
|
||||
name = Twitter Signin
|
||||
description = Adds support for "Sign in with Twitter"
|
||||
core = 7.x
|
||||
dependencies[] = twitter
|
||||
dependencies[] = oauth_common
|
||||
configure = admin/config/services/twitter/signin
|
||||
|
||||
; Information added by drupal.org packaging script on 2011-12-03
|
||||
version = "7.x-3.0-beta4"
|
||||
core = "7.x"
|
||||
project = "twitter"
|
||||
datestamp = "1322940643"
|
||||
|
209
sites/all/modules/twitter/twitter_signin/twitter_signin.module
Normal file
209
sites/all/modules/twitter/twitter_signin/twitter_signin.module
Normal file
@@ -0,0 +1,209 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function twitter_signin_menu() {
|
||||
$items['twitter/redirect'] = array(
|
||||
'title' => 'Twitter Redirect',
|
||||
'page callback' => 'twitter_signin_redirect',
|
||||
'access callback' => TRUE,
|
||||
'type' => MENU_CALLBACK,
|
||||
);
|
||||
|
||||
$items['admin/config/services/twitter/signin'] = array(
|
||||
'title' => 'Sign-in',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('twitter_signin_admin_settings'),
|
||||
'access arguments' => array('administer site configuration'),
|
||||
'file' => 'twitter_signin.pages.inc',
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'weight' => 5,
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_block_info().
|
||||
*/
|
||||
function twitter_signin_block_info() {
|
||||
$block[0]['info'] = t('Sign in with Twitter');
|
||||
return $block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_block_view().
|
||||
*/
|
||||
function twitter_signin_block_view($delta) {
|
||||
global $user;
|
||||
|
||||
if (!$user->uid && _twitter_use_oauth()) {
|
||||
$block['subject'] = t('Sign in with Twitter');
|
||||
$block['content'] = twitter_signin_button();
|
||||
return $block;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns an image link for signing in with twitter
|
||||
*/
|
||||
function twitter_signin_button() {
|
||||
$img = drupal_get_path('module', 'twitter_signin') . '/images/' . variable_get('twitter_signin_button', 'Sign-in-with-Twitter-lighter-small.png');
|
||||
|
||||
return l(theme('image', array('path' => $img, 'alt' => t('Sign in with Twitter'))), 'twitter/redirect', array('html' => TRUE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit handler for twitter signin
|
||||
*/
|
||||
function twitter_signin_redirect() {
|
||||
module_load_include('lib.php', 'oauth');
|
||||
module_load_include('lib.php', 'twitter');
|
||||
module_load_include('inc', 'twitter');
|
||||
|
||||
$key = variable_get('twitter_consumer_key', '');
|
||||
$secret = variable_get('twitter_consumer_secret', '');
|
||||
$twitter = new TwitterOAuth($key, $secret);
|
||||
$token = $twitter->get_request_token();
|
||||
|
||||
$_SESSION['twitter_oauth']['token'] = $token;
|
||||
$_SESSION['twitter_oauth']['destination'] = $_SERVER['HTTP_REFERER'];
|
||||
$_SESSION['twitter_oauth']['signin'] = TRUE;
|
||||
drupal_goto($twitter->get_authenticate_url($token));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_form_alter().
|
||||
*/
|
||||
function twitter_signin_form_alter(&$form, $form_state, $form_id) {
|
||||
// This only applies if we've got OAuth / signin enabled.
|
||||
if (!_twitter_use_oauth()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($form_id == 'twitter_oauth_callback_form' && isset($_SESSION['twitter_oauth']['signin'])) {
|
||||
$form['#submit'] = array_merge(array('twitter_signin_oauth_callback_submit'), $form['#submit']);
|
||||
}
|
||||
|
||||
if ($form_id == 'user_login' || $form_id == 'user_login_block') {
|
||||
$items = array();
|
||||
$items[] = twitter_signin_button();
|
||||
|
||||
$form['twitter_signin'] = array(
|
||||
'#markup' => theme('item_list', array('items' => $items)),
|
||||
);
|
||||
}
|
||||
elseif ($form_id == 'user_register_form' && isset($_SESSION['twitter']['values'])) {
|
||||
$form['account']['name']['#default_value'] = $_SESSION['twitter']['values']['screen_name'];
|
||||
$form['auth_twitter'] = array(
|
||||
'#type' => 'hidden',
|
||||
'#value' => $_SESSION['twitter']['values']['user_id'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Form submit for the OAuth callback. Here we add in sign-in specific handling
|
||||
*/
|
||||
function twitter_signin_oauth_callback_submit(&$form, &$form_state) {
|
||||
global $user;
|
||||
|
||||
$success = FALSE;
|
||||
|
||||
$key = variable_get('twitter_consumer_key', '');
|
||||
$secret = variable_get('twitter_consumer_secret', '');
|
||||
$response = $form_state['twitter_oauth']['response'];
|
||||
|
||||
$account = user_external_load($response['user_id']);
|
||||
if (isset($account->uid)) {
|
||||
user_external_login($account, $response);
|
||||
$success = TRUE;
|
||||
}
|
||||
elseif ($uid = db_query("SELECT uid FROM {twitter_account} WHERE twitter_uid = :twitter_uid", array(':twitter_uid' => $response['user_id']))->fetchField()) {
|
||||
// We have an existing twitter account - set it up for login
|
||||
$account = user_load($uid);
|
||||
$edit["authname_twitter"] = $response['user_id'];
|
||||
user_save($account, $edit);
|
||||
$user = $account;
|
||||
$form_state['twitter_oauth']['account'] = $account;
|
||||
$success = TRUE;
|
||||
}
|
||||
else {
|
||||
// No existing user account, let's see if we can register.
|
||||
if (variable_get('twitter_signin_register', 0)) {
|
||||
// Check for a nickname collision
|
||||
$account = array_shift(user_load_multiple(array(), array('name' => $response['screen_name'])));
|
||||
if (empty($account->uid)) {
|
||||
$edit = array(
|
||||
'name' => $response['screen_name'],
|
||||
'pass' => user_password(),
|
||||
'init' => $response['screen_name'],
|
||||
'status' => 1,
|
||||
"authname_twitter" => $response['user_id'],
|
||||
'access' => REQUEST_TIME,
|
||||
);
|
||||
$account = user_save('', $edit);
|
||||
$user = $account;
|
||||
$form_state['twitter_oauth']['account'] = $account;
|
||||
$success = TRUE;
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('The nickname %name is already in use on this site, please register below with a new nick name, or @login to continue.', array('%name' => $response['screen_name'], '@login' => url('user/login'))), 'warning');
|
||||
}
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('Please log in or register to relate your Twitter account with a user.'));
|
||||
}
|
||||
}
|
||||
|
||||
if (!$success) {
|
||||
$_SESSION['twitter']['values'] = $response;
|
||||
drupal_goto('user/register');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_user_insert()
|
||||
*
|
||||
* Relates a Twitter account with a just created user account if the user
|
||||
* signed in with Twitter but did not have an account in the site yet
|
||||
*/
|
||||
function twitter_signin_user_insert(&$edit, $account, $category) {
|
||||
_twitter_signin_add_account($account);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_user_insert()
|
||||
*
|
||||
* Relates a Twitter account with an existing user account if the user
|
||||
* signed in with Twitter
|
||||
*/
|
||||
function twitter_signin_user_login(&$edit, $account) {
|
||||
_twitter_signin_add_account($account);
|
||||
}
|
||||
|
||||
/**
|
||||
* Relates a user account with a twitter account
|
||||
*
|
||||
* @param $account
|
||||
* The Drupal user account
|
||||
*/
|
||||
function _twitter_signin_add_account($account) {
|
||||
if (isset($_SESSION['twitter']['values'])) {
|
||||
module_load_include('lib.php', 'twitter');
|
||||
module_load_include('inc', 'twitter');
|
||||
$key = variable_get('twitter_consumer_key', '');
|
||||
$secret = variable_get('twitter_consumer_secret', '');
|
||||
$response = $_SESSION['twitter']['values'];
|
||||
|
||||
$twitter = new TwitterOAuth($key, $secret, $response['oauth_token'], $response['oauth_token_secret']);
|
||||
$twitter_account = $twitter->users_show($response['screen_name']);
|
||||
$twitter_account->set_auth($response);
|
||||
twitter_account_save($twitter_account, TRUE, $account);
|
||||
|
||||
unset($_SESSION['twitter']);
|
||||
|
||||
drupal_set_message(t('You have related a Twitter account with your user. Next time you can sign in with Twitter.'));
|
||||
}
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @todo Please document this function.
|
||||
* @see http://drupal.org/node/1354
|
||||
*/
|
||||
function twitter_signin_admin_settings($form, &$form_state) {
|
||||
$form = array();
|
||||
|
||||
$img_path = drupal_get_path('module', 'twitter_signin') . '/images';
|
||||
$results = file_scan_directory($img_path, '/.png/');
|
||||
|
||||
$options = array();
|
||||
foreach ($results as $image) {
|
||||
$options[$image->filename] = theme('image', array('path' => $image->uri));
|
||||
}
|
||||
|
||||
$form['twitter_signin_button'] = array(
|
||||
'#type' => 'radios',
|
||||
'#title' => t('Select sign-in button'),
|
||||
'#options' => $options,
|
||||
'#default_value' => variable_get('twitter_signin_button', 'Sign-in-with-Twitter-lighter-small.png'),
|
||||
);
|
||||
|
||||
$form['twitter_signin_register'] = array(
|
||||
'#title' => t('Automatically register new users'),
|
||||
'#type' => 'radios',
|
||||
'#options' => array(t('No'), t('Yes')),
|
||||
'#default_value' => variable_get('twitter_signin_register', 0),
|
||||
'#description' => t('Warning, if you enable this, new user accounts will be created without email addresses.'),
|
||||
);
|
||||
|
||||
return system_settings_form($form);
|
||||
}
|
69
sites/all/modules/twitter/twitter_views_field_handlers.inc
Normal file
69
sites/all/modules/twitter/twitter_views_field_handlers.inc
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Process Twitter-style @usernames and URLs before filtering XSS.
|
||||
*/
|
||||
class twitter_views_handler_field_xss extends views_handler_field {
|
||||
function option_definition() {
|
||||
$conf = TwitterConf::instance();
|
||||
$options = parent::option_definition();
|
||||
$options['link_urls'] = array('default' => TRUE);
|
||||
$options['link_usernames'] = array('default' => TRUE);
|
||||
$options['link_hashtags'] = array('default' => FALSE);
|
||||
$options['hashtags_url'] = array('default' => 'http://' . $conf->get('search') . '/search?q=%23');
|
||||
return $options;
|
||||
}
|
||||
|
||||
function options_form(&$form, &$form_state) {
|
||||
parent::options_form($form, $form_state);
|
||||
$form['link_urls'] = array(
|
||||
'#title' => t('Link urls to their destinations'),
|
||||
'#type' => 'checkbox',
|
||||
'#default_value' => !empty($this->options['link_urls']),
|
||||
);
|
||||
$form['link_usernames'] = array(
|
||||
'#title' => t('Link Twitter @usernames to their Twitter.com urls'),
|
||||
'#type' => 'checkbox',
|
||||
'#default_value' => !empty($this->options['link_usernames']),
|
||||
);
|
||||
$form['link_hashtags'] = array(
|
||||
'#title' => t('Link Twitter #hashtags to another url'),
|
||||
'#type' => 'checkbox',
|
||||
'#default_value' => !empty($this->options['link_hashtags']),
|
||||
);
|
||||
$form['hashtags_url'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#default_value' => $this->options['hashtags_url'],
|
||||
'#process' => array('ctools_dependent_process'),
|
||||
'#dependency' => array('edit-options-link-hashtags' => array(TRUE)),
|
||||
);
|
||||
}
|
||||
|
||||
function render($values) {
|
||||
$value = $values->{$this->field_alias};
|
||||
if (!empty($this->options['link_urls'])) {
|
||||
$filter = new stdClass;
|
||||
$filter->settings = array(
|
||||
'filter_url_length' => 496,
|
||||
);
|
||||
$value = _filter_url($value, $filter);
|
||||
}
|
||||
if (!empty($this->options['link_usernames'])) {
|
||||
$conf = TwitterConf::instance();
|
||||
$value = _twitter_filter_text($value, '@', 'http://' . $conf->get('host') . '/');
|
||||
} if (!empty($this->options['link_hashtags']) && valid_url($this->options['hashtags_url'])) {
|
||||
$value = _twitter_filter_text($value, '#', url($this->options['hashtags_url']));
|
||||
}
|
||||
return filter_xss($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Field handler to provide simple renderer that turns a URL into a clickable link.
|
||||
*/
|
||||
class twitter_views_handler_field_profile_image extends views_handler_field {
|
||||
function render($values) {
|
||||
$value = $values->{$this->field_alias};
|
||||
return theme('image', array('path' => $value));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user