2690 Commits
master ... v3

Author SHA1 Message Date
tsmethurst
49a80a3c40 [PLUGIN][ActivityPub][TESTS] Add GoToSocial test fixtures 2022-10-21 13:01:32 +02:00
tsmethurst
97114e38e0 [PLUGIN][ActivityPub][TESTS] Replace invalid URL in fixtures 2022-10-21 11:47:27 +01:00
tsmethurst
2df30e2987 [PLUGIN][ActivityPub] Sign outgoing GET requests on behalf of relevant actor 2022-10-21 11:31:35 +01:00
tsmethurst
3b3ded5212 [PLUGIN][ActivityPub] Fix incorrect use of ActivityPubActor::create, should be ::createOrUpdate 2022-10-21 11:31:35 +01:00
tsmethurst
dc240fae49 [DOCKER] Fix incorrect script mount in worker 2022-10-21 11:31:35 +01:00
5cbb1627f2 [COMPONENT][Language] Fix collection query build event incorrectly not setting 'actor_language' join
Thanks to tsmethurst <tobi.smethurst@protonmail.com> for finding the error
2022-10-21 11:31:35 +01:00
46ff8aacd2 [UTIL][TemporaryFile] Silence warnings in critical section inside TemporaryFile 2022-10-21 11:30:47 +01:00
c4d6df4637 [TESTS] Fixup failing tests
Not a permanent solution
2022-10-21 11:30:37 +01:00
053bc38792 [TESTS] Fix tests 2022-10-19 22:39:17 +01:00
2fd46ca886 [TOOLS] Continue raising PHPStan level to 6 2022-10-19 22:39:17 +01:00
c31f3d4997 [TOOLS] Continue raising PHPStan to level 6 2022-10-19 22:39:17 +01:00
Hugo Sales
e6bb418fe6 [TOOLS] Begin raising PHPStan level to 6 2022-10-19 22:38:49 +01:00
fed2242a56 [TOOLS] Raise PHPStan level to 5 and fix associated error, fixing some bugs in the process 2022-10-19 22:38:49 +01:00
edeee49af9 [TOOLS] Fix errors pointed out by PHPStan level 4 2022-10-19 22:38:49 +01:00
4d7742e0e1 [OAuth2] Fix error in plugin install 2022-10-19 22:38:49 +01:00
76f2cdd212 [DEPENDENCIES] Update dependencies 2022-10-19 22:38:44 +01:00
a2aa45fb1f [DOCS] Expand developer Event documentation 2022-04-03 22:05:19 +01:00
d4b7e990ce [CORE][Event] Make all events return \EventResult, enforced at container build time 2022-04-03 21:40:32 +01:00
aef1fac536 [SECURITY] Refactor security hardening code and disable unused stream wrappers
Ensure unwanted enviorment variables are removed from the actual
global environment rather than just the `$_ENV` superglobal variable

Disable stream wrappers, as this is an unexpected feature for most
developers and can be exploited. For instance, `phar://` can be used
to override any class and thus provide code execution (through
`__wakeup` or `__costruct`, for instance). Not a complete solution, as
`php://` can also be abused, but we can't disable it as it gets used
_somewhere_ in our dependencies
2022-04-03 18:02:54 +01:00
556ac85061 [PLUGIN][Pinboard] For tag list request, respond with the most common variant and the corresponding count for each canon tag 2022-04-01 02:10:12 +01:00
539104ec33 [PLUGIN][Pinboard] Refactor and cleanup code 2022-04-01 00:17:57 +01:00
74ffd261b8 [PLUGIN][Pinboard] Implement tag handling 2022-04-01 00:16:04 +01:00
ca9945a4be [ENTITY][Actor][COMPONENT][Tag] Add Actor->getNoteTags(?string $note_type) which gets a cached list of NoteTags for notes of type $note_type for the actor 2022-04-01 00:11:01 +01:00
08587b6942 [COMPONENT][Link][Tag] Refactor to make it easier to create links or tags from other places 2022-04-01 00:09:25 +01:00
1664293cf7 [PLUGIN][Pinboard] Change token to user user ID rather than nickname, to avoid complications with it possibly changing 2022-03-31 22:06:37 +01:00
94ab4ce8c4 [PLUGIN][Pinboard] Invalidate token and it's cache when actor information is changed via ActorForms 2022-03-31 03:47:14 +01:00
dd70de20da [PLUGIN][Pinboard] Implement token authentication and settings page, allowing the user to enable, disable, refresh or consult their token 2022-03-31 03:29:31 +01:00
ded9c86054 [CORE][DB] Add DB::refetch, which refetches an entity from the database, so it's managed and definitely up to date (use when wanting to update entities from cache) 2022-03-31 03:29:31 +01:00
20e07c9140 [CORE][DB] Make DB::dql return an object rather than an array if limit 1 is specified 2022-03-31 03:29:31 +01:00
4e2f6545ec [COMPONENT][Person][PLUGIN][WebHooks] Rename person settings section from 'others' to 'api' 2022-03-31 03:29:31 +01:00
f6a8f44420 [COMPONENT][Person][TEMPLATES] Move persosn settings template from core to the component 2022-03-31 03:29:31 +01:00
fd71d6ee7d [PLUGIN][UnboundGroup] Finish implementation 2022-03-29 00:57:41 +01:00
dfc5918c2c [PLUGIN][ActivityPub] Federate out Service information in Activities 2022-03-28 23:54:19 +01:00
83599ef866 [CORE][Modules][Plugin] version should be static 2022-03-28 23:54:18 +01:00
fa82306f6f [COMPONENT][Posting] Blog posts should be Articles by default 2022-03-28 23:54:18 +01:00
10f71e9fed [UI][TEMPLATES] Fix note text template. Use rendered content directly 2022-03-28 23:23:07 +01:00
e2501ee927 [PLUGIN][Pinboard] Implement remaining API endpoints, restructure, fix template 2022-03-28 23:23:07 +01:00
a9665177ea [PLUGIN][Blog] Move to plugins, mistakenly was in components 2022-03-28 20:59:16 +01:00
41861d284c [COMPONENT][Circle] Correct self tags settings text 2022-03-28 20:59:16 +01:00
bd868a2675 [PLUGINS][Pinboard] Add initial implementation of Pinboard API, lacking authentication, tags and feed endpoints 2022-03-28 20:59:16 +01:00
87e35716c1 [UTIL] Add Formatting::explode(array , string ) 2022-03-28 20:59:16 +01:00
dac94f53cd [CORE][Entity] Rename createOrUpdate to 'checkExistingAndCreateOrUpdate', remove update feature from 'create' and add 'createOrUpdate' and fix users 2022-03-28 20:59:15 +01:00
b10c359dec [DEPENDENCIES] Update dependencies 2022-03-28 20:59:15 +01:00
483983790a [CORE][Router] Rename \App\Core\Router\Router to \App\Core\Router and merge \App\Core\Router\RouteLoader with \App\Core\Router 2022-03-28 20:59:15 +01:00
60af9f5e9b [CORE][Queue] Rename App\Core\Queue\Queue to App\Core\Queue 2022-03-28 20:59:15 +01:00
abe35428da [CORE][DB] Rename App\Core\DB\DB to App\Core\DB 2022-03-28 20:59:14 +01:00
ca5520edbf [PLUGIN][WebHooks] Add hook for subscriptions 2022-03-28 20:59:14 +01:00
e3e14c53ef [PLUGIN][ActivityPub] Model/Note->toJson federate the url, even though it's the same as the id 2022-03-28 20:59:14 +01:00
be33c20614 [PLUGIN][ActivityPub] Improve flexibility of Type layer, accomodate more elaborate understanding of Group Announces after FEP-2100 development 2022-03-28 20:58:48 +01:00
7305a725cb [PLUGIN][UnboundGroup] First steps on implementing AP FEP-2100 2022-03-28 20:57:43 +01:00
fd4c3b0e68 [PLUGIN][Embed][Test] Move Test to correct location 2022-03-28 20:53:50 +01:00
16f51e5143 [COMPONENT][Notification] ->getSubscribers() should not be pre-included
Notification bug fix on Subscription component
Correct docblock
2022-03-28 20:53:19 +01:00
ba4230447e [COMPONENT][Group] Add orderBy to query, as otherwise the feed order is wrong 2022-03-28 20:49:28 +01:00
7463044971 [COMPONENT][Circle] Ensure strict typing on getter 2022-03-28 20:48:29 +01:00
7027633ed5 [PLUGIN][WebHooks] Make request method configurable
This way, PUT can be used, which doesn't seem to be the standard, so isn't the default, but which makes sense to me, as it doesn't have a response, which we don't care about anyway
2022-03-24 00:51:00 +00:00
48b42c539c [PLUGINS][WebHooks] Use ActivityPub to serialize the activity, so the object is included 2022-03-24 00:51:00 +00:00
d41a67a9f9 [PLUGIN][WebHooks] Add WebHooks plugin, which allows for sending a POST request to an external resource when a notification or a follow occurs 2022-03-24 00:51:00 +00:00
13f22c911c [COMPONENT][Notification] Feed: Fix typo in query 2022-03-23 16:09:13 +00:00
56b8710b26 [PLUGIN][ActivityPub][Notification] Fix some issues with targetting 2022-03-23 13:23:44 +00:00
e63c310d70 [COMPONENT][Notification] Always pre-add Actor subscribers when notifying 2022-03-23 13:23:44 +00:00
03f449035a [PLUGIN][ActivityPub][Model][Activity] Sometimes we don't have a local, move on with encapsulated 2022-03-23 13:23:44 +00:00
8808195a80 [PLUGIN][ActivityPub][Test] Test @language handling 2022-03-23 13:23:44 +00:00
45344c80d1 [PLUGIN][ActivityPub][Model][Note] Fix @language handling 2022-03-23 13:23:43 +00:00
7eddbd343d [PLUGIN][ActivityPub][Test] Add Like{Note} fixture 2022-03-23 13:23:43 +00:00
259d2da05a [CORE][Controller] Add default handler for when using http methods 2022-03-23 13:23:43 +00:00
2f7fdf6ee4 [PLUGIN][ActivityPub][Test] Activity: Create Page
Fixed a couple of bugs
2022-03-19 22:21:35 +00:00
6955872e05 [PLUGIN][ActivityPub][Model][Activity] toJson: When in activity context, use object's context if available 2022-03-19 22:20:32 +00:00
23e88b30a6 [COMPONENT][Blog] This is not used for replies 2022-03-19 22:18:33 +00:00
60713878f0 [TESTS] Load languages prior to remaining fixtures 2022-03-19 22:18:00 +00:00
06c67b31c2 [PLUGIN][ActivityPub][Model][Note] toJson: Respect source attribute and @language from context 2022-03-19 18:01:25 +00:00
a08b661779 [COMPONENT][Group] Cast integer string to int when getting group from context 2022-03-19 18:01:25 +00:00
0649a5154c [PLUGIN][ActivityPub][Test][Model][Note] fromJson 2022-03-19 18:01:24 +00:00
91fecd77ba [TOOLS][DOCKER] Use a more robust way to check for database availability 2022-03-19 17:20:12 +00:00
e22fe55bbe [TOOLS] Add .well-known/acme-challenge/ root certbot to nginx container, to allow certbot certificate renewals 2022-03-19 07:32:01 +00:00
dd62825169 [PLUGIN][ActivityPub][Model][Note] fromJson: Respect source attribute and @language from context 2022-03-15 17:49:09 +00:00
27706d63f4 [PLUGIN][OAuth] Fix login for OAuth 2022-03-14 21:41:22 +00:00
20f690c532 [TESTS] Fix a couple of issues from last changes 2022-03-14 18:37:39 +00:00
888c3798b7 [COMPONENT][Notification] Make logic more generic and robust
Fixed various bugs

Some important concepts to bear in mind:

* Notification: Associated with activities, won't be reconstructed
together with objects, can be thought of as transient

* Attention: Associated with objects, will be reconstructed with them, can
be thought as persistent

* Notifications and Attentions have no direct implications.

* Mentions are a specific form of attentions in notes, leads to the creation of Attentions.

Finally,

Potential PHP issue detected and reported: https://github.com/php/php-src/issues/8199
`static::method()` from a non static context (such as a class method) calls `__call`, rather than
the expected `__callStatic`. Can be fixed by using `(static fn() => static::method())()`, but the
usage of the magic method is strictly unnecessary in this case.
2022-03-14 11:37:09 +00:00
e1cceac150 [CORE][Form][TESTS] Fix FormTest::handle 2022-03-13 18:53:53 +00:00
63ef9292f3 [DEPENDENCIES] Update dependencies 2022-03-13 18:17:32 +00:00
cbae649991 [PLUGIN][ActivityPub][TESTS] Move ActivityPub test fixtures to new facility 2022-03-13 18:11:11 +00:00
1d8bba3949 [TESTS][MODULES] Move Test Fixtures to tests/fixtures folder and add support for loading fixtures from components and plugins 2022-03-13 18:00:21 +00:00
18864ca9fa [CONTROLLER][Security] Override the _next form field in Security->register to redirect to login page 2022-03-13 16:01:51 +00:00
390c532456 [PLUGIN][ActivityPub][Tests] Create Actor Tests 2022-03-13 16:00:35 +00:00
636cb681d6 [PLUGIN][ActivityPub][Tests] Create a TestCase for the plugin 2022-03-13 15:54:14 +00:00
7d84323df4 [PLUGIN][ActivityPub][Tests] Add some fixtures for GNU social's 2022-03-13 15:53:21 +00:00
2d7850ccfb [PLUGIN][ActivityPub][Tests] Borrow test fixtures from Lemmy 2022-03-13 15:52:48 +00:00
d8108dbc32 [COMPONENT][Posting] Fix request handling issues that resulted from splitting creation and controller 2022-03-13 15:52:48 +00:00
cf05d3dbb0 [ENTITY][TESTS] Fix Note->isVisibleTo with and associated test 2022-03-13 15:03:03 +00:00
eb3c848fc8 [TOOLS][TESTS] Ensure database schema is up to date in tests 2022-03-13 14:22:18 +00:00
5c708af272 [CORE][Form] Remove unweildy return of form errors from Form::handle 2022-03-13 14:19:56 +00:00
8433771465 [TOOLING][TESTS] Allow specifying any phpunit flag when invoking make
Examples:
  make test -- --filter 'method'
  make test -- directory
2022-03-10 01:23:36 +00:00
0ce5eba355 [PLUGINS][Favourite][RepeatNote][DeleteNote][WebMonetization] Make use of 'activitypub_handler' more readable 2022-03-10 00:40:54 +00:00
9a9eed1457 [CORE][Router][Form] Add Router::sanitizeLocalURL and use it in Form::forceRedirect 2022-03-09 20:51:42 +00:00
f540711948 [CORE][GNUsocial] Remove Session parameter, as it's no longer a service. Use session from Request 2022-03-09 20:51:42 +00:00
c870fd44e3 [PLUGIN][Embed] Fix test folder name, so Symfony doesn't attempt to autowire it 2022-03-09 20:51:42 +00:00
c30fcead74 [DEPENDENCIES] Move from Symfony 5.4 to 6 and update all other packages, where applicable 2022-03-09 20:51:42 +00:00
301421ea15 [SECURITY][EVENT] Remove deprecated uses of Symfony Guard. Add LoginSucess and LoginFailure events 2022-03-09 20:51:16 +00:00
4d77f3497d [COMPONENT][Person][TESTS] Fix Controller/PersonSettingsTest 2022-03-09 14:24:50 +00:00
f735e6b31c [TESTS] Fix Util/CommonTest 2022-03-09 14:24:50 +00:00
893d299e29 [UTIL][Common] Respect detect language setting
Minor bug fix
2022-03-09 14:24:50 +00:00
d857baa0f1 [TESTS] Fix Twig/ExtensionTest 2022-03-09 01:43:58 +00:00
0441f030ab [COMPONENT][Group][TESTS] Fix Entity/GroupTest 2022-03-09 01:43:51 +00:00
cac68a6372 [TESTS] Fix Entity/NoteTest 2022-03-09 01:42:11 +00:00
28453c585f [COMPONENT][Attachment][TESTS] Fix Entity/AttachmentThumbnailTest 2022-03-09 01:42:11 +00:00
5c7b079df5 [COMPONENT][Attachment][Controller] Security fix: We were not ensuring that attachment was related to note 2022-03-09 01:42:11 +00:00
47f03d4c9f [COMPONENT][Attachment][TESTS] Fix Entity/AttachmentTest 2022-03-09 01:42:06 +00:00
cc4f967186 [TESTS] Fix Circle SelfTags Setting test 2022-03-09 01:40:35 +00:00
ff06a2656a [COMPONENT][Group][Entity] Useless URI column removed
Add table to Makefile backup
2022-03-09 01:40:34 +00:00
d5fd7da707 [TESTS] Fix Core/RouterTest 2022-03-09 01:40:34 +00:00
1bdeac7076 [TESTS] Fix Core/DB/UpdateListenerTest 2022-03-09 01:40:34 +00:00
e67ed58286 [TESTS] Temporarily Disable Controller/AdminTest: It seems we are repeating values arbitrarily - specially in plugins, and the generated file is just nonsense overall really, wrong sections and stuff 2022-03-09 01:40:34 +00:00
487791d606 [TESTS] Fix Core/ControllerTest 2022-03-09 01:40:33 +00:00
813e66e83e [TESTS] Fix Core/CacheTest 2022-03-09 01:40:33 +00:00
88ace68627 [TESTS] Fix Controller/FeedsTest 2022-03-09 01:40:33 +00:00
416665d830 [COMPONENT][Attachment][TESTS] Fix Controller/AttachmentTest 2022-03-09 01:40:09 +00:00
808a3b219e [TESTS] Specify non-null fields for use of creating actors in tests 2022-03-09 01:37:11 +00:00
df40dd7c66 [TESTS] Add support for loading test suites from plugins and components 2022-03-09 01:37:11 +00:00
afa8443949 [TESTS] Fix some failing tests broken by restructuring and dependency updates 2022-03-09 01:37:11 +00:00
46de2d47e9 [TOOLS] Add explicit return types to fix deprecation warnings raised by PHPUnit 2022-03-09 01:37:10 +00:00
372cf91fbc [TOOLS][TESTS] Split tests into different test suites 2022-03-09 01:37:10 +00:00
9c9e86649a [TESTS] Fix Controller/SecurityTest 2022-03-09 01:37:10 +00:00
a37ce86d05 [TESTS] Fix DataFixtures 2022-03-07 15:26:27 +00:00
9a0c74cb0c [CORE][SECURITY] Replicate 'next' form submission feature on login form 2022-03-07 15:26:27 +00:00
46c91a4b39 [I18N] Fix use of string concatenations in translations 2022-03-07 15:26:26 +00:00
3f14ad0f69 [COMPONENT][Posting][FORM] Refactor Posting form to use a form action with a separate controller and the new Form::forceRedirect 2022-03-07 15:26:26 +00:00
6ddc176faf [CORE][Form] Add facilities for automattically adding a _next field to all forms, which can be customized by the in Form::create and defaults to the current URL. Usage of RedirectedException should mostly be replaced with Form::forceRedirect 2022-03-07 15:26:26 +00:00
d629976322 [UTIL][Notification] Remove deprecated code 2022-03-07 15:26:24 +00:00
1a0c9e720f [COMPONENT][FreeNetwork] Start using queues
[COMPONENT][Notification] Start using queues
[PLUGIN][ActivityPub] Start using queues
2022-03-05 14:23:08 +00:00
6fa5ec3218 [CORE][Queue] Fix some minor issues 2022-03-05 14:22:44 +00:00
626b4263f1 [PLUGIN][ActivityPub][Model][Actor] Fix internal logic for updating
Actors
2022-03-05 14:19:12 +00:00
1daa314c55 [COMPONENT][Posting][FORM] Refactor Posting form to use a form action with a separate controller and the new Form::forceRedirect 2022-03-04 15:16:19 +00:00
7814697f82 [UTIL][EXCEPTION] Forward given status code in RedirectException 2022-03-04 15:15:04 +00:00
7a8d67f1e2 [CORE][Controller] Fix bug where a JSON request could not recieve a redirect response 2022-03-04 15:14:05 +00:00
94449c9153 [CORE][Form] Add facilities for automattically adding a _next field to all forms, which can be customized by the in Form::create and defaults to the current URL. Usage of RedirectedException should mostly be replaced with Form::forceRedirect 2022-03-04 15:12:35 +00:00
7c9b01c516 [UTIL][Common] Add Common::getRequest 2022-03-04 15:09:39 +00:00
6cae6c925d [TOOLS] Keep feed table in delete content Make rule 2022-03-01 18:12:58 +00:00
12fb876a6d [PLUGIN][ActivityPub][Model][Activity] No @context to exclude when object is not embedded. 2022-03-01 18:00:24 +00:00
7ca4330f17 [TEMPLATES] Tweak note complimentary info to not output empty <span>s 2022-03-01 17:58:53 +00:00
802a8d124a [TOOLS] For delete content, restore local_groups and actor_subscriptions 2022-03-01 17:57:39 +00:00
87354c06bf [TEMPLATES] For note complementary info, compare identity by the ID, rather than nickname, which is not unique 2022-03-01 17:39:14 +00:00
5600218924 [TWIG][I18N] Remove unnecessary wrappers for translation functions, use them directly 2022-03-01 17:25:51 +00:00
90f9378bca [TEMPLATES] Use transList and trans function for note complimentary info 2022-03-01 13:46:06 +00:00
070f53c10e [TWIG][I18N] Add transList function, which uses _m_list 2022-03-01 13:46:01 +00:00
f73e9c12ba [CORE][I18n] Add I18n::_m_list, which formats an array of elements into a list. Limited to 5 elements, as that should be enough (tm) and ICU doesn't support this natively 2022-03-01 13:45:40 +00:00
fc203e2e38 [TWIG][TEMPLATES] Rename transchoice to trans and make it more generic 2022-03-01 13:45:11 +00:00
b3374333f3 [TEMPLATES][I18N] Fixup use of trans filter, in favour of trans tags. These are much more flexible and facilitate parameterized translations, rather than using concats. The only appropriate use of the trans filter is when a whole string in a variable needs to be translated (which should probably be avoided anyway) 2022-03-01 13:16:11 +00:00
0b864e85fd [TEMPLATES] Fixup uses of deprecated noteView, in favour of new NoteFactory facility 2022-03-01 11:23:39 +00:00
a9a60bbd92 [COMPONENT][Posting] Clarify use of cache in note replies when posting 2022-03-01 11:19:47 +00:00
4cc4d06b11 [CORE][Cache] Fix bug where empty lists must be stored as a string in Redis (not supported natively), so we can't directly push to it, but the key still exists 2022-03-01 11:07:21 +00:00
f8c1b0f71d [TOOLS] Add Make rule to delete content, but keep actors and sequences 2022-02-28 23:37:16 +00:00
43ae3add43 [TEMPLATE] Update uses of NoteFactory macro, to pass the values seperately, rather than inside a converstation key 2022-02-28 15:48:47 +00:00
d5f90a1206 [ENTITY][Note][CONFIG] Use getListPartialCache for getReplies. Add feeds/cached_replies config entry to control how many replies get cached 2022-02-28 15:47:38 +00:00
85ce6bfd41 [CORE][Cache] Add getListPartialCache, which allows for fetching a list and backing only a portion of it in the cache (useful for feeds and replies to notes, for instance) 2022-02-28 15:47:38 +00:00
46c4bd9099 [COMPONENT][Conversation] Sort conversation correctly 2022-02-28 15:47:38 +00:00
35f3781a32 [COMPONENT][Collection] Add mechanism for specifying the ordering of note and actor queries 2022-02-28 15:47:38 +00:00
45c7888676 [TOOLS] Run CS-Fixer on whole project 2022-02-28 15:47:37 +00:00
255c44bbf0 [ENTITY][LocalUser] Don't use FILTER_SANITIZE_EMAIL, use just want to validate. Up to the user to fix any errors. Use setter, rather than duplicate it's code 2022-02-28 15:47:37 +00:00
5188a473d0 [TOOLS] Fix errors reported by PHPStan 2022-02-28 15:47:37 +00:00
8c15d21591 [TOOLS] Add update-dependencies and update-autocode Make rules 2022-02-28 15:47:37 +00:00
df640f60d2 [DEPENDENCIES] Update dependencies 2022-02-28 15:47:37 +00:00
6e85a4adbb [CONFIG] Change default config to make media files (attachments and their thumbnails) to a subfolder to file, so cleanup scripts can avoid files meant to be persistent (plugin files, certificates) 2022-02-28 15:47:37 +00:00
eccf21edef [TOOLS][PLUGINS][OAuth2] Add mechanism to allow plugins to have an install script. Add script for generating keys for OAuth 2022-02-28 15:47:32 +00:00
9b86794cda [CSS] Details inside another details (accordion widget) will represent their 'open/close feedback arrows' properly now 2022-02-28 13:09:12 +00:00
077975136e [CARDS][Note] Both 'in conversation' and 'in reply to' link to note's conversation. The former anchors it's id, while the latter it's parent id 2022-02-28 12:43:40 +00:00
5495a3c5ec [ENTITY][Note] NoteType now becomes a varchar as predicted 2022-02-27 02:04:48 +00:00
a9b34b75b6 [PLUGIN][TreeNotes] Correct cache issues and iterate functionality
- Replies ordering now correct
- Replies count added
- Posting adds new replies to cache (when concerning replies cache is not empty) and increments replies count
- Configuration to specify number of in-tree replies shown added
- TreeNotes templates was moved from core to plugin
- Button to read more replies was added
2022-02-27 01:46:25 +00:00
2f539d176d [TWIG] Implement transchoice for ICU plural translations 2022-02-27 00:44:23 +00:00
d4c908c194 [CORE][Cache] Implement listPushRight 2022-02-27 00:44:23 +00:00
b630d530f4 [PLUGIN][ActivityPub][Postman] JSON_UNESCAPED_SLASHES
Only record webfinger matches for acct
2022-02-25 13:52:56 +00:00
26a50618b0 [CARDS][Note] Notification targets are now used as target info, instead of previous reply dependant implementation [COMPONENTS][Group] Feed title is applied to GroupFeed view 2022-02-25 13:12:16 +00:00
d5731e6351 [COMPONENT][Notification] Consider attention properly in notes 2022-02-25 13:12:16 +00:00
f5e92de62d [PLUGIN][ActivityPub][Util][Explorer] Simplify fetching Actor by URI 2022-02-25 13:12:14 +00:00
7c80277436 [CSS] Fix header position on >1080p displays 2022-02-24 19:16:41 +00:00
4754593cde [PLUGIN][ActivityPub][Model][Activity] If the object is wrapped in an activity, exclude the @context 2022-02-24 19:07:46 +00:00
d12038a9f8 [CSS] Complete refactor, removing all useless rules, squashing related separate files, and limiting folder depth 2022-02-24 19:05:14 +00:00
af02bc7b32 [PLUGIN][ActivityPub][Model][Note] Replace our directMessage extension with LitePub's 2022-02-23 22:27:32 +00:00
bc3d5245f5 [PLUGIN][ActivityPub][Model][Note] Handle Mentions properly 2022-02-23 22:27:32 +00:00
f3c2e49e3f [PLUGIN][ActivityPub] Correct @context 2022-02-23 22:27:30 +00:00
05b7f2c28b [CORE][DB] Remove doc from deprecated DB::merge and add about DB::refresh 2022-02-23 17:42:20 +00:00
338ea0ea58 [COMPONENTS][Group] Group view template now extends the Collection of Notes view instead of trying to reinvent the wheel [COMPONENTS][Conversation] Replaced deprecated DB::merge with DB::persist 2022-02-23 17:01:41 +00:00
57a07ef74f [COMPONENT][FreeNetwork] Add to Search the query expression 2022-02-21 04:53:12 +00:00
c380cbd846 [COMPONENT][FreeNetwork] Mention and Group tags in notes are handled differently 2022-02-21 04:52:30 +00:00
7678e155d9 [COMPONENT][Search] Ensure title is set when saving as feed 2022-02-21 04:49:08 +00:00
59380ed2ac [COMPONENT][Collection] If invalid term, just perform a regular search for it 2022-02-21 04:48:18 +00:00
1e310aa124 [PLUGIN][ActivityPub][FreeNetwork] DB::findBy won't work if not commited first 2022-02-20 15:01:49 +00:00
José Marques
8b0e9c7890 [UTIL][Form][ActorForms] Fix Full Name validate: Tried to mb_strln on null
If the trim(string) is empty, then store null without further ado
2022-02-20 05:03:55 +00:00
f1caabd296 [CARDS][Note] Note factory template macro created, allows Notes to be represented with completely different macros/blocks, possible to extend types through additional events. Compact Notes have a max height, content can be scrolled by [CSS] Avatars, and Embed attachments now have a max-block-size which acts independently of image orientation 2022-02-20 05:03:54 +00:00
a71c16d654 [COMPONENTS][Posting] Fixed issue where an embed attachment would violate Note's conversation_id not null constraint
Conversation was only assigned after storing Note's attachments
2022-02-20 05:03:41 +00:00
ecfd6b5ad2 [PLUGIN][ActivityPub][Model][Note] Sometimes content is explicitely null 2022-02-20 05:03:40 +00:00
496701ce73 [PLUGIN][ActivityPub][Inbox] Add event for notifications triggered by AP Inbox 2022-02-20 05:03:40 +00:00
e86dbad6d6 [COMPONENT][Notification] Don't explode with understandable duplicate notifications
This is common when a duplicate federation request is received
2022-02-20 05:03:40 +00:00
6f3e760c63 [PLUGIN][ActivityPub][Inbox] Separate handler by method 2022-02-20 05:03:40 +00:00
51cccd0155 [PLUGIN][ActivityPub] Simplify DB usage 2022-02-20 05:03:40 +00:00
9523927b8e [PLUGIN][ActivityPub][Model][Note] There may be no attachments, nor tags, nor to, nor cc 2022-02-19 05:46:48 +00:00
ebbd8bf1e4 [PLUGIN][ActivityPub][HTTPSignatures] Fix wrong assumption that sha512 is used in hs2019 2022-02-19 04:49:50 +00:00
7a59d5a002 [PLUGIN][ActivityPub][HTTPSignatures] Validate draft-cavage-http-signatures-11 2022-02-19 04:49:50 +00:00
52ae5fa690 [PLUGIN][ActivityPub][Inbox] Improve logs 2022-02-19 04:49:50 +00:00
99f7e7cd79 [PLUGIN][ActivityPub][Model][Note] Handle group scope properly 2022-02-19 04:49:50 +00:00
27635d8ec2 [PLUGIN][ActivityPub][Model][Note] Add name property as note title 2022-02-19 04:49:49 +00:00
0a741903a1 [PLUGIN][ActivityPub][Model][Note] Federate content out 2022-02-19 04:49:49 +00:00
8f60fc4685 [PLUGIN][ActivityPub][Model][Note] Federate attentions out 2022-02-19 04:49:49 +00:00
8cf60275e6 [PLUGIN][ActivityPub][Model][Note] Add support to Pages 2022-02-19 04:49:49 +00:00
75837af412 [CSS] Replacing problematic special Unicode glyphs
A browser will use Unicode glyphs from other font families if the glyph in question is not present for the current typeface. This leads to unnerving situations, whereby setting content through pseudo-selectors will cause text to misalign. And no, line-height won't make a difference in this case. This happens because fonts have different heights. Another reason may reside on CSS3 having pseudo selectors but not really having a proper spec for them to begin with.
2022-02-19 04:01:47 +00:00
03a475b642 [TWIG] Form layout is all new, since extending form_div_layout.html.twig was quite limiting
[COMPONENTS][Posting] It is now visible on Actor profiles [COMPONENTS][Search] Overall rework of search results template, there's also additional help text added [CSS] Header no longer translucent, font sizes yet more consistent, replies marker less pronounced, and font hierarchy is now applied in both weight and size
2022-02-19 04:01:47 +00:00
b69f4a46c5 [COMPONENT][Posting] Page should flush with a different notification 2022-02-16 19:35:27 +00:00
b6ed0b4c6c [CORE][Actor] Fix generic profile route 2022-02-16 18:53:08 +00:00
cee2d143c9 [COMPONENT][Posting] Add storeLocalPage
Minor refactoring and bug fixing
2022-02-16 18:53:08 +00:00
2d5fac7a89 [COMPONENT][Notification] Re-introduce the concept of note attention
Minor refactoring and bug fixing
2022-02-16 18:53:08 +00:00
e70acd5c3b [UTIL][HTML] HTML abstraction class was extended with a more specialised Heading class
This little abstraction layer made it a bit easier to add a different title to a Note or Actor Feed Collection template, from whichever controller that uses it. Please, bear in mind, that abstract templates such as those found in Components\Collection, may act in a very 'declarative' way upon using them. This makes it difficult to dynamically choose what type of header is used without undergoing a mining operation in the likes of a pyramid of doom. Hence, this _little_ change.
2022-02-16 18:53:08 +00:00
f66e178dfc [CORE][Actor][Settings] Fix nickname change and refactor Core Form::handle so it's harder to repeat these mistakes again
Minor improvements on actor->getLocal
2022-02-16 18:53:07 +00:00
397b54a207 [PLUGIN][Bundles] Refactor BlogCollections to Bundles 2022-02-16 18:53:07 +00:00
33e1d3eb20 [COMPONENT][Conversation] Use Router::url's _fragment for anchor 2022-02-16 18:53:07 +00:00
54b9ec48b4 [COMPONENT][Collection][FeedController] Fix group scope, we should use the IN context actor to check the group 2022-02-16 18:53:07 +00:00
40590bbd11 [COMPONENT][Group] Restore settings functionality 2022-02-16 18:53:07 +00:00
5b94973079 [COMPONENTS][Posting] Form is no longer added to RightPanel if not on a feed|conversation|groups route 2022-02-16 18:53:07 +00:00
9d9abf8afb [CARDS][Note] Removed incorrect aria attributes, polished Note card 2022-02-16 18:53:06 +00:00
be0a2d27e2 [COMPONENT][Blog] Initial support for in group blogs 2022-02-16 18:53:06 +00:00
bf23ae2dcf [ENTITY][Note] Some notes aren't exactly just a note but rather a Page, or further (like happening or poll), this is only initial support for that
It prolly will become a varchar instead of an enum, so plugins can add their own note types
2022-02-16 18:53:06 +00:00
33e768c298 [COMPONENT][Group][Controller] Separate feed from other group features 2022-02-15 17:13:16 +00:00
3f9c86f0df [COMPONENT][Group] More flexible member roles than only isAdmin
Refactor terminology of canAdmin to match current roles system
2022-02-14 05:02:10 +00:00
bc63c3727a [COMPONENT][GROUP] Allow to create a group as private and prioritise group scope on Posting in that context 2022-02-14 05:02:09 +00:00
090a087832 [COMPONENT][Group] Check nickname on register 2022-02-14 01:21:40 +00:00
262b14a977 [COMPONENT][Collection] Organisation no longer is an actor type but rather a type of Actor Group 2022-02-14 00:41:57 +00:00
10d1a7ed2a [PLUGIN][ActivityPub] Implement Group Inbox POST 2022-02-13 23:15:00 +00:00
3ae8f8213f [GROUP] Notifity group subscribers of new activity concerning the group 2022-02-13 23:15:00 +00:00
66323c5a73 [PLUGIN][ActivityPub] Fix several issues with target and notifications inserted by AP 2022-02-13 23:14:59 +00:00
56c884026f [COMPONENT][Notification] We must record remote notifications because of feeds 2022-02-13 23:14:59 +00:00
62bf788b90 [CORE][Note] Implement private group scope properly 2022-02-13 23:14:59 +00:00
6500e99b69 [COMPONENT][Posting] Respect context actor concerning visibility and In sorting 2022-02-13 23:14:58 +00:00
cda1568db5 [TEMPLATES][Cards][Blocks] Provide both actor uri and url, as well as full mention guidance 2022-02-13 23:14:58 +00:00
1f2638d15a [ROUTES] Remove ActorCircle holdover route 2022-02-11 15:31:47 +00:00
6b4fa8c303 [COMPONENT][Notification] Additional check to avoid unnecessary notifications 2022-02-11 15:31:47 +00:00
17733f32d6 [PLUGIN][ActivityPub] Implement Group Outbox
Fix various minor issues
2022-02-11 10:06:01 +00:00
fb3e900b28 [CORE] Add CONFIG_ prefix to environment whitelist
Fixed minor issues with Commong:config of env not being included and ported to local social yaml

Fixed some regressions introduced with [CORE] Unset sensitive information from the environment
2022-02-11 10:05:58 +00:00
416451a519 [CORE][Actor] Simplify logic so more is reused between different types of actors
Minor bug fixes
2022-02-11 00:27:03 +00:00
1f1524c2b3 [GROUP] Simplify logic by making Actor::Organisation a type of Actor::Group
Some minor bug fixes
2022-02-11 00:26:43 +00:00
35e907f7b2 [CARDS][Note] Note's 'in reply to' information added, overall polish of feeds templates and proper titles added for every single section that makes up a note 2022-02-09 18:49:34 +00:00
79bb258ba6 [CSS] Further dialing of sizes and media queries for a better mobile UX 2022-02-08 17:14:28 +00:00
80dfea6812 [CARDS][Note] Note's actions are now inside the same div as Note's complementary info, overall footprint of replies diminished 2022-02-08 17:01:58 +00:00
f6b19d2a0f [CARDS][Note] Note's actions are now inside the same div as Note's complementary info, overall footprint of replies diminished 2022-02-08 16:13:46 +00:00
67a2387b31 [CARDS][Note] Removed note's complementary info related to the current user everywhere, which was criticized from being redundant 2022-02-08 15:19:33 +00:00
5d0b8930e1 [COMPONENTS][Conversation] Removed redundant complementary information from notes replied to 2022-02-08 14:43:39 +00:00
22741702bf [CSS] Replaced .section-details-subtitle summary, .section-details-title summary outline to a border, since Firefox ESR doesn't apply border-radius to outline 2022-02-08 14:22:52 +00:00
ba131bdb16 [CSS] Background noise is back, default_theme directory hierarchy simplified
[PLUGINS][Oomox] Fixed issue where resetting colours when no entity was present would lead to an error (it expected an entity, but NULL was given)
2022-02-08 14:12:59 +00:00
7b0667109d [CARDS][Note] Note actions are now displayed at the end
Due to space constraint on mobile screens, prior actions placement proved to be a problem. Additionally, note replies are now separated from their parent, allowing more horizontal space to be used if necessary/more reply depth to be presented in a reasonable fashion.
2022-02-08 01:26:25 +00:00
5cd3bc3206 [CSS] Touch devices are now able to scroll horizontally on note author information 2022-02-08 00:30:15 +00:00
79d022e850 [CSS] Fixing note attachments padding, height and allowing their wrap when limited space is available 2022-02-08 00:18:24 +00:00
cb393ca554 [CARDS][Note] Fix note replies from calling note macro as if it was still part of the same template 2022-02-08 00:05:51 +00:00
99593a19ef [CSS] Default theme polish work, more consistent font sizes and improved dark theme colors 2022-02-07 23:54:29 +00:00
9a53f94b77 [TWIG] Replaced getRightPanelBlocks with addRightPanelBlock, provides more control on block placement
[COMPONENTS][RightPanel] Refactored template, improved clarity, and added Posting form related macros

[PLUGINS][NoteTypeFeedFilter] Removed icons from template, added them through CSS to further improve performance
2022-02-07 20:29:14 +00:00
d6666cf209 [CSS] Aligned details marker arrows 2022-02-07 02:46:08 +00:00
b3d582f665 [PLUGINS][AttachmentCollections] Fixed "Error: Expected Doctrine\ORM\Query\Lexer::T_IDENTIFIER, got 'Plugin\AttachmentCollections\Entity\AttachmentCollection'"
[TWIG] Cards are now divided into blocks and macros, additional macros done, attachments page no longer inside cards directory
[CARDS][Navigation] Now using macros to create section, details, and nav elements
2022-02-07 01:54:04 +00:00
2b9f70f89f [PLUGINS][BlogCollections] Entities and base plugin and controller done 2022-02-07 01:52:35 +00:00
e0ceddc2e6 [CSS] Replaced fooobar:not([foo=bar], [foo2=bar2]) rule, as Firefox ESR 78.x doesn't support that specific syntax 2022-02-04 21:12:22 +00:00
81f6d496c6 [PLUGIN][OAuth2] Fix some static issues 2022-02-04 19:56:17 +00:00
4dd976eb22 [ENTITY][Note] Added function getRenderedSplit, return an array of paragraphs/line breaks
[PLUGINS][Favourite] Foreign keys now properly defined on schema

[CARDS][Note] Note text is now hidden by default if too many paragraphs/line breaks are present, BlogCollection plugin will certainly need this feature
2022-02-04 16:07:24 +00:00
Bruno Aleixo
fb76775716 [TOOLS][COMPONENTS][CORE] Ran cs-fixer on all files 2022-01-30 16:41:54 +00:00
Bruno Aleixo
162b01e2c5 [CORE] Unset sensitive information from the environment 2022-01-30 16:39:43 +00:00
afd1211852 [CSS] Using accent-color rule to stylize checkbox 2022-01-28 23:15:01 +00:00
8f8070036c [CSS] Eliminated repeated rules, improved icon alignment, and removed checkbox and radio custom styling
Browser specific quirks made it impossible to stylize checkbox and radio buttons. High DPI, custom default font sizes and/or custom GTK themes make it very difficult to keep it consistent.
2022-01-28 18:21:04 +00:00
2e6f91f34e [FORM][ActorForms] Fullname length is now validated prior to being set 2022-01-27 17:53:02 +00:00
5036b72a71 [ENTITY][Actor] Nickname is lower case transformed when generating 'actor_view_nickname', making sure that actor pages are linked accordingly 2022-01-27 17:19:50 +00:00
a17a514bfd [CONTROLLER][Security] Further sanity checks and validation done on email entry 2022-01-27 17:08:20 +00:00
1576d253a5 [CONTROLLER][UserPanel] Email is now sanitized and validated before calling corresponding setter 2022-01-27 16:59:43 +00:00
64a698d255 [COMPONENTS][Search] Polished search template for a clearer header hierarchy 2022-01-27 02:17:41 +00:00
ab6dabf4f7 [CSS] Fix issue where panels wouldn't scroll independantly 2022-01-27 01:53:30 +00:00
222e1fbb2b [PLUGINS][AttachmentShowRelated] Replacing h2 with span, its supposed to be complementary content, not main 2022-01-27 01:13:18 +00:00
117549bf1e [PLUGINS][Favourite] Remove favourite action properly removes note_favourite Entity now [COMPONENTS][Collection] Simplyfying feed-action-details template section
[COMPONENTS] Documentation work [PLUGINS] Documentation work
2022-01-27 00:54:27 +00:00
adf484f58a [COMPONENTS][Posting] No error to ignore was reported on line 161, removed ignore
[PLUGINS][Directory] Further documentation work

[CORE][Controller] Separating workflows, setting proper return types

[TWIG][Security] Removing unused stylesheet calls
2022-01-26 20:54:55 +00:00
16e7d6cff7 [COMPONENTS] Documenting methods with high cognitive complexity, specifically in Group and Posting components
[PLUGINS][Directory] Updating docs, @params weren't set correctly
2022-01-26 20:01:37 +00:00
6a5312aca9 [CORE][GNUsocial] social.local.yaml is now updated with the proper node name 2022-01-26 18:46:31 +00:00
14bb1b2876 [COMPONENTS][Conversation] Note being replied to now appears before Posting's own form, RightPanel is also open by default on smaller screens when the current route is 'conversation_reply_to' 2022-01-25 19:18:42 +00:00
c7c5fe7979 [PLUGIN][OAuth2] Add 'me' field to token responses 2022-01-25 16:07:39 +00:00
fa0d02a9ac [PLUGIN][OAuth2] Start adding OAuth2 support with client registration
This hardcodes the user, and has some other issues, so it is not yet
complete.

We follow mastodon's spec for automatic client registration, available
at both `/api/v1/apps` and a more reasonable `/oauth/client`. This
accepts a JSON POST with the client info and returns JSON with a
`client_id` and a `client_secret`, to be used with `/oauth/authorize`
and `/oauth/token`. It also, seemingly, requires returning an `id`
with unclear purpose.

The `/oauth/token` endpoint doesn't currently return a `me` field.
2022-01-25 13:35:44 +00:00
4736146b80 [TOOLS] Update autocode, allow for abstract entity classes, derive namespace from file rather than using 'get_declared_classes' 2022-01-25 13:35:44 +00:00
e3bfb1ebc5 [CSS] .note-info text will automatically crop when no space is available, on hover will show contents 2022-01-25 00:02:38 +00:00
ee04571f4d [TWIG] Various fixes related to header elements hierarchy
Widgets shouldn't have a header element from here forward, since their location varies
2022-01-23 19:46:47 +00:00
bf07fa1ade [COMPONENTS][Collection] Added PrependActorsCollection event [COMPONENTS][Group] Added getGroupCreateForm, used in PrependActorsCollection event to build create a new Group form view
[COMPONENTS][LeftPanel] Removed onEndShowStyles event since the corresponding CSS needed is now consolidated into the default_theme itself [COMPONENTS][RightPanel] Deleted components/RightPanel/RightPanel.php, since its only method (onEndShowStyles) wasn't needed anymore
2022-01-23 19:07:39 +00:00
e4a3438d55 [CORE][I18n] Fixing 'file_get_contents(): Argument #1 () must be of type string, Symfony\Component\Finder\SplFileInfo given' error by using Symfony's Finder to iterate through existing files 2022-01-23 19:07:39 +00:00
6b1c6f603e [CORE][ActorLocalRoles] Improve Roles 2022-01-22 18:47:56 +00:00
5f243f68be [DEPENDENCIES] Add symfony/psr-http-message-bridge 2022-01-21 22:05:34 +00:00
68c3204e71 [DEPENDENCIES] Update dependencies 2022-01-21 22:05:34 +00:00
559f6d650b [COMPONENT][Language] Fix template name in language sorting 2022-01-21 22:05:34 +00:00
3d9edd1db8 [COMPONENTS][LeftPanel] Edit feeds page polish, existing links are shown in a grid, saving space
[COMPONENTS][Collection] Fixing details summary class [PLUGINS][WebMonetization] Fixing widget details summary class
2022-01-21 22:05:34 +00:00
402300fe93 [COMPONENTS][Search] Fixing Search form incorrect class names 2022-01-21 22:05:34 +00:00
e2e1b0172d [COMPONENTS][Collection] Actors view template ordering section polished [PLUGINS][RepeatNote] Note to be repeated now uses full note card
[CSS] Simplyfying rules, re-ordering and removing unnecessary and costly 'display: flex' rules
[CARDS][Note] Minimal note macro has info inside the note itself now, since horizontal space is limited
2022-01-21 22:05:33 +00:00
f731850f5c [CSS] .section-widget class and derivatives replaced as .frame-section, since a widget implies a simple element with a specific function 2022-01-21 22:05:33 +00:00
7d546e8901 [CSS] Improved performance, reduced padding [COMPONENTS][LeftPanel] Consolidated CSS into base.css [COMPONENTS][RightPanel] Consolidated CSS into base.css [PLUGINS][WebMonetization] Replaced fieldset with section
Accessibility tests failed if the fieldset had no legend, since it
wasn't really neeeded, it was replaced as another element.
2022-01-21 22:05:33 +00:00
bdeb3bcff5 [PLUGIN][ActivityPub] Federate Actor of types other than Person
Fix some other minor bugs
2022-01-21 22:05:31 +00:00
25b2847201 [TOOLS][AYY1] Improve accesibility testing to save images and compare the differences against a reference (tests/screenshots/ 2022-01-21 21:03:09 +00:00
23d45ffab7 [UTIL][Formatting] Mention prefix was hardcoded, fixed. 2022-01-21 21:03:09 +00:00
b253ce5e70 [DOCS][Design] Add guidelines menu entry 2022-01-21 21:03:09 +00:00
c4f9e58e8d [COMPONENTS][Attachment] Fixed typo on attachmentShowWithNote, where the template called was somehow replaced with a child of it 2022-01-21 21:03:09 +00:00
6ab740d780 [COMPONENT][Search][UI] Fix template, which included the search builder form inside the search form, chaos ensuing 2022-01-21 21:03:09 +00:00
de795b78f9 [DOCKER][DEPENDENCIES] Restructure PHP Dockerfile to install each package in separate layers and add WikiMedia texvc 2022-01-21 21:03:09 +00:00
29d498770c [COMPONENTS][Group] Create a group route added, template polished
[COMPONENTS][Circle] Removed any Group related route from shouldAddToRightPanel event
[CARDS][Profile] Block should now allow inline long nicknames to not
break
2022-01-21 21:03:09 +00:00
d7039b1c5c [COMPONENTS][Group] Create a group route added, template polished
[COMPONENTS][Circle] Removed any Group related route from shouldAddToRightPanel event
[CARDS][Profile] Block should now allow inline long nicknames to not
break
2022-01-21 21:03:08 +00:00
1856af68b3 [PLUGIN][RepeatNote][COMPONENTS][Posting] Review and fix RepeatNote. Handle attachment lives in Posting 2022-01-21 21:03:08 +00:00
9bd1f42843 [TOOLS] Use sudo to remove files 2022-01-21 21:03:08 +00:00
145c88d43f [ENTITY][Note] Only attempt to find mentions if we have content 2022-01-21 21:03:08 +00:00
4717dde12e [TWIG][I18N] Improve base template facilitate translations of the accessibility panel text 2022-01-21 21:03:08 +00:00
c028a601a5 [COMPONENTS][Group] Create a group route added, template polished
[COMPONENTS][Circle] Removed any Group related route from shouldAddToRightPanel event
[CARDS][Profile] Block should now allow inline long nicknames to not
break
2022-01-21 21:03:08 +00:00
692ecf1c99 [TWIG] Improved templates HTML structure, removed unnecessary element nesting, and refactored content sectioning
[COMPONENTS][Search] Refactored widget event as 'PrependRightPanel' (making it able to accomodate more generic blocks)
2022-01-21 21:03:08 +00:00
242fe3fd6e [PLUGINS][PinnedNotes] Replacing arbitary size values with common variables 2022-01-21 21:03:08 +00:00
dbdf1d9b0b [CSS] Fixed footer responsiveness, since its content wouldn't wrap up from insuficient space for all of its content 2022-01-21 21:03:08 +00:00
7daa61500d [COMPONENTS][Collection] Notes collection template now has a default title
[CARDS][Note] Removed note actions from minimal note block
2022-01-21 21:03:07 +00:00
077cbcf424 [TWIG] Improved accessibility menu
[COMPONENTS][RightPanel] Content form row is now preceeded by the content type form row
2022-01-21 21:03:07 +00:00
04431885aa [PLUGIN][PinnedNotes] Fix ActivityPub config 2022-01-21 21:03:07 +00:00
b8a35f9d6d [PLUGIN][WebMonetization] Fix ActivityPub config 2022-01-21 21:03:07 +00:00
184d0246a5 [COMPONENTS][RightPanel] AppendRightPanelBlock event refactored,
replaced with src/Twig/Rintime::getRightPanelBlocks
[COMPONENTS] Re-ordered onAppendRightPanelBlock event calls arguments for improved consistency across events
2022-01-21 21:03:07 +00:00
da7ae5e1f5 [TESTS][A11Y] Login and check all user pages for accessibility 2022-01-21 21:03:07 +00:00
9e4aed84f8 [PLUGIN][LatexNotes] add LaTeX support for notes 2022-01-21 21:03:07 +00:00
db42ade2b6 [PLUGIN][MarkdownNotes] add markdown support for notes 2022-01-21 21:03:07 +00:00
06d11d8337 [PLUGINS[WebMonetization] Basic activityPub support 2022-01-21 21:03:07 +00:00
148dd6db50 [PLUGINS][PinnedNotes] Basic activityPub support 2022-01-21 21:03:06 +00:00
21c7912702 [PLUGIN][Pinned Notes] Allow user to pin his notes 2022-01-21 21:03:06 +00:00
f7cbfbff8c [COMPONENT][Collection] Add event to render html before drawing feed 2022-01-21 21:03:06 +00:00
3f0d996dc9 [COMPONENT][Tag] Fix event handling 2022-01-21 21:03:06 +00:00
9e891ed020 [TOOLS][PHPStan] Ignore errors due to lack of namespace in CodeCeption acceptance tester 2022-01-21 21:03:06 +00:00
6c6c0270c5 [TESTS][CodeCeption] Update acceptance tests to remove accesibility test kludge 2022-01-21 21:03:06 +00:00
a59997b41f [TOOLS][DOCKER][A11Y] Switch to Pa11y CI and don't run it 'integrated' with codeception, since there was no good way to share cookies 2022-01-21 21:03:06 +00:00
d542be1df4 [ACCESSIBILITY] Fix regressions in panel checkboxes and accessibility menu accesskeys
Accessibility menu accesskey regressions introduced with [ACCESSIBILITY][BASE] Accessibility menu was unreachable.
2022-01-13 19:47:41 +00:00
eff9318c1d [UTIL][Formatting] Mention title is not always defined 2022-01-13 18:07:19 +00:00
fa9df9962e [COMPONENTS][Conversation] Route 'conversation_mute' now has the
corresponding conversation view embedded, user is also redirected
properly
[PLUGINS][Favourite] Fixed typo
2022-01-13 17:47:47 +00:00
859bf0c0bf [CONTROLLER][UserPanel] Notification settings panel debug information added for future reference 2022-01-13 16:24:23 +00:00
d29e28b829 [CORE][Entity] Replaced get_called_class() calls with static::class since the former is deprecated 2022-01-13 16:24:12 +00:00
14b03c7137 [UI][UserPanel] Do not try to re-set an unchanged nickname 2022-01-12 17:46:13 +00:00
480f570238 [CORE][SECURITY][HTML] Refactor Security::sanitize to HTML::sanitize
Update composer dependencies, move more general deps from ActivityPub to Core
2022-01-12 17:12:58 +00:00
968b1751fd [CSS] Further styling optimizations, compacting common rules. Removed select dropdown images, since they are no longer required 2022-01-12 16:42:33 +00:00
c8daa82c1d [TWIG] Replaced base.css @import with HTML link imports
According to 'High Performance Web Sites' (ISBN 10: 0596529309), @import has a negative impact on web page performance. Since all imports dependant on base.css will only start downloading after that one is fully gathered.
2022-01-12 16:32:47 +00:00
600a1511cb [TWIG] Removed all instances were 'arrow-down' icon was called in twig templates, replaced it's intended feedback by using :after pseudo-selector within CSS
In user panel render time reduced dramatically, by ~70ms. Said icon was requested by twig >10 times.
2022-01-12 16:07:28 +00:00
59b8bdf99b [PLUGIN][ActivityPub] Provide ActivityStreams 2.0 responses for every Collection
Implemented ActivityPub Outbox
2022-01-11 20:30:25 +00:00
f3a7e8f04d [TOOLS] Remove CodeCeption files from composer autoload-dev, since they're not available before installing, and ignore errors in PHPStan 2022-01-10 23:14:43 +00:00
65504b72bb [TOOLS] Setup pa11y to run on pages after codeception 2022-01-10 23:09:39 +00:00
José Marques
d713429d88 [CORE][Nickname] Properly set nickname for existing accounts 2022-01-10 11:33:13 +00:00
1056bc661f [COMPONENT][FreeNetwork] Restore Galaxy feed 2022-01-10 10:29:55 +00:00
f40eb3955f [TOOLS] Update makefile to add an acceptance and accesibility testing target 2022-01-09 14:45:33 +00:00
b2b445d21e [TOOLS][DOCKER] Add pa11y and nginx container to tooling toolchain 2022-01-09 14:44:56 +00:00
528f6df240 [TOOLS][PHPStan] Ignore autogenerated Codeception classes 2022-01-09 14:44:08 +00:00
894c78bf99 [TOOLS] Keep git in docker image, since we use patched composer packages, temporarily 2022-01-09 14:43:33 +00:00
38baa192d8 [DEPENDENCIES][TOOL] Add codeception and bootstrap it for acceptance and accessibility testing 2022-01-09 14:42:16 +00:00
a697399a6f [PLUGIN][DeleteNote][Favourite][ProfileColor][RepeatNote][WebMonetization] Refactor, cleanup and cache results 2022-01-09 12:29:34 +00:00
cdf1d67d0f [CORE][Cache] Workaround to redis not allowing empty lists 2022-01-09 12:29:34 +00:00
06ece5b72e [COMPONENT][Collection] Only run queries if the criteria is not empty 2022-01-09 12:29:34 +00:00
da6d3bd351 [COMPONENT][Collection] Use current locale 2022-01-09 12:29:34 +00:00
c835fc6aca [COMPONENT][Collection][Feed][Attachment][Feed][Language][Tag] Refactor and consolidate Search and Feed query mechanisms into Collection. Remame 'onSearch' events to 'onCollectionQuery' 2022-01-09 12:29:34 +00:00
57604b3851 [PLUGIN][NoteTypeFilter] Always show filtering options 2022-01-09 12:29:34 +00:00
b1abd81aca [DEPENDENCIES] Update dependencies 2022-01-08 00:11:12 +00:00
5cfed3d536 [TWIG] Display errors in templates that display forms with form_start 2022-01-08 00:11:08 +00:00
0758d6145b [COMPONENT][Collection][CONTROLLER][Collection] Use null-safe calls to attempt to get a language 2022-01-08 00:07:32 +00:00
d17f276419 [COMPONENTS][Conversation] Added missing foreign keys to ConversationMute Entity
Fixed 'is_muted' variable check logic that impeded the Conversation from being muted
2022-01-07 21:14:51 +00:00
fc57b3290e [COMPONENTS][Search] Polished results page HTML view 2022-01-07 21:14:51 +00:00
1438433859 [PLUGINS][NoteTypeFeedFilter] Polish feed actions HTML, adding proper anchor titles and better user feedback when a filter in applied
[COMPONENTS][Collection] Notes feed template HTML polish to accomodate changes needed for NoteTypeFeedFilter
2022-01-07 21:14:51 +00:00
cb1dc4c10f [PLUGIN][WebMonetization] Adding Web Monetization plugin which allows for donations using the Web Monetizations protocol 2022-01-07 14:55:35 -03:00
9cf8970603 [TEMPLATES][Base] AppendToHead event added to base template 2022-01-07 14:53:55 -03:00
c3d58c350e [COMPONENTS][Collections] Iterating documentation 2022-01-07 09:23:37 -03:00
e056920de4 [COMPONENT][Subscription] Fix Notifications 2022-01-06 12:13:11 +00:00
0c245fcb6e [COMPONENTS][Subscription] Subscribe Actor action implemented
[TWIG] AddProfileAction event added
[CARDS][Profile] Refactor and restyling to accomodate Actor actions
2022-01-06 12:13:10 +00:00
0d1ab2c9cf [SECURITY][Register] New users should have their current browser language set as first language preference 2022-01-05 04:19:35 +00:00
3f8fab0021 [PLUGIN][Favourite] Fix routes 2022-01-05 04:19:35 +00:00
cd6ce3542e [COMPONENT][Circle] Move circles to a component, various bug fixes
Mention links are now correct
2022-01-05 04:19:22 +00:00
627d92b290 [COMPONENT][Tag] Improve Note Tag Handling and start extracting Circles logic out of the plugin, various bug fixes 2022-01-05 01:30:02 +00:00
ee007befa4 [COMPONENT][Posting] DB::Flush after Notification and fix minor issues with In targets 2022-01-05 01:30:01 +00:00
9df9c6a19c [COMPONENT][Collection] Make MetaCollectionPlugin a trait and abstract collection delete and name update 2022-01-05 01:30:00 +00:00
754135743e [COMPONENT][Subscription] Move respective routes to component 2022-01-05 01:29:27 +00:00
5a0bbfc795 [UTIL][Common][I18N] Use actor's preferred language for _m and utility to retrieve current language even when no actor is logged in 2022-01-05 01:29:26 +00:00
6247dd4c1a [COMPONENT][RightPanel] Display form errors 2022-01-04 18:58:32 +00:00
de8eab2cf8 [CORE][FORM][FormTypeNonceExtension] Add a nonce to all forms with a CSRF token 2022-01-04 18:58:32 +00:00
b7e4f79ccc [CORE][Cache] Add Cache::incr which increments a value at , atomically, in the case of Redis 2022-01-04 18:58:32 +00:00
a5b5362be2 [DOCS][Designer] General guidelines for styling initiated
Added wireframes of default page, dividing page into 4 distinct general
areas.

Added CSS classes reference table.
2022-01-04 00:02:21 +00:00
d444ea7963 [COMPONENT][Conversation] Refactor and fix Conversation component 2022-01-03 21:20:27 +00:00
a729a8eddb [COMPONENT][Collection] Pass current actor and their top language to query, if not otherwise specified 2022-01-03 21:20:26 +00:00
a8a8cc4046 [COMPONENT][Posting] Plumb in reply_to and redirecto to GET from 2022-01-03 21:20:26 +00:00
7d38c927e1 [ENTITY][Note][CACHE] Consolidate cache keys to helper function and add ensureCanInteract 2022-01-03 21:20:26 +00:00
135bf8bc68 [COMPONENTS][Conversation] Documented respective Controller
[PLUGINS][TreeNotes] Documentation added, feedFormatTree explained in detail
2022-01-03 19:26:17 +00:00
5a31258190 [COMPONENTS][Conversation] Further documentation work, expected arguments explained in more detail 2022-01-03 19:26:17 +00:00
f5fc7b6cd1 [CORE][Controller] Add facility for either returning null or throwing, from Controller->{int,string,bool} 2022-01-03 18:02:33 +00:00
141c5f6785 [COMPONENT][Collection][CONTROLLER][Collection] Add utility method to call Feed::query in Collection, which handles getting and passing the page 2022-01-03 18:02:33 +00:00
07b65584ff [COMPONENTS][Posting] Replaced is_int() with is_numeric(), casting target to int when using Actor getter
From php-stan: is int with string evaluates to false

Thus, the change was made in order to behave as intended
2022-01-03 17:58:48 +00:00
4ae160b0f8 [PLUGINS][AttachmentShowRelated] Fix onEndShowStyles condition to add proper stylesheet to array 2022-01-03 17:51:19 +00:00
a622b175bc [DEPENDENCIES] Update dependencies 2022-01-03 16:38:51 +00:00
9ea230d12b [COMPONENT][Subscription] Implement subscription handlers 2022-01-03 02:23:06 +00:00
fe087b2217 [PLUGIN][ActivityPub] Accept Undo Follow 2022-01-03 02:23:06 +00:00
a9ea49d34c [TOOLS][DOC] Add documentation to functions flagged by doc-check 2022-01-03 02:23:06 +00:00
9e0a2dd4a0 [TOOLS] Fix errors found by PHPStan 2022-01-03 02:23:06 +00:00
8fa04bb47d [EVENT][AddFeedActions] Add bool param which denotes whether the feed is empty. [PLUGIN][NoteTypeFeedFilter] Don't show filters if the feed is empty 2022-01-03 02:23:06 +00:00
d5a6fa924b [COMPONENT][Conversation][ENTITY][ConversationMute] Rename Conversation{Block,Mute} 2022-01-03 02:23:05 +00:00
ba0b0629b7 [TOOLS] Fix deprecations in php-doc-check by providing my own implementation 2022-01-03 02:18:44 +00:00
27276ba379 [CONFIG] Rename streams/notes_per_page to feeds/entries_per_page 2022-01-03 02:18:44 +00:00
ea5a4df1a4 [UI][PLUGIN][Directory] Add UI for Directory listing ordering. This uses a GET parameter, which subits the field in order_by and the operator in order_op. Using order_by=filed^ is still supported 2022-01-03 02:18:44 +00:00
6cfb69d64b [COMPONENT][Subscription] Start component 2022-01-03 02:18:44 +00:00
5fa8056899 [COMPONENT][Collection] Refactoring: Further work in abstracting collections 2022-01-03 02:18:43 +00:00
def5f36c25 [PLUGIN][ActivityPub][Inbox] Accept Follow Activity
Improve how Core Activity is handled in general
2022-01-02 23:50:16 +00:00
afb7ae0f75 [CORE][Util][Exception] Add log context to BugFoundException 2022-01-02 23:50:15 +00:00
064288e33b [CSS] Applying correct border-radius to note-info and adding a greater margin on note-complementary, in case its the last of type 2022-01-02 23:50:15 +00:00
c7ea56d571 [CSS] Fixing checkboxes from displaying background cropped 2022-01-02 23:50:15 +00:00
17b46b9aeb [CSS] Fixed radio button, it didnt change its own background upon being checked, making it invisible 2022-01-02 23:50:15 +00:00
28424402ec [CONTROLLER][CollectionController] Refactored methods names and form
titles
[PLUGINS][AttachmentCollections] Renamed respective Controller to
differentiate it between The Controller and itself, renamed templates
and removed unnecessary HTML from templates
2022-01-02 23:50:15 +00:00
7ad39fdc83 [PLUGINS][Repeat] Added onNoteDeleteRelated event
Using DB::merge to increment attachment lives when repeating a note,
since it's getting deprecated in the future, an alternative needs to
replace it here
2022-01-02 23:50:15 +00:00
d5080890ac [PLUGINS][Favourite] Added onNoteDeleteRelated event
All favourite entities are now removed from note_favourite table when the respective note
is deleted. Documented the favourNote and unfavourNote methods
2022-01-02 23:50:15 +00:00
f42e91d2bc [CORE][Controller] Allow plugins to override redirect responses 2022-01-02 23:50:14 +00:00
362fc6c7dd [CORE][Controller] Set some safe default headers for every response 2022-01-02 23:50:14 +00:00
046731a05a [COMPONENT][Avatar] Save title if possible, delete correctly, no early flushes
[PLUGIN][ActivityPub] Minor bug fixes in Actor translation
2022-01-02 23:50:14 +00:00
d27e8610d6 [CORE][DB] DB:removeBy Accept class name instead of table. 2022-01-02 23:50:14 +00:00
b7574500f8 [COMPONENT][FreeNetwork] Set discovery cors enabled by default 2022-01-01 23:57:28 +00:00
6ea45df3b8 [COMPONENT][FreeNetwork] Set JRD as the default mimetype for .well-know/host-meta 2022-01-01 23:57:28 +00:00
d6cd33019d [UI][PLUGIN][Directory] Add sort options to UI 2022-01-01 22:18:18 +00:00
5662210a2d [UI][PLUGIN][Directory] Use a single template for all results 2022-01-01 22:18:18 +00:00
b1fbf7d6ef [PLUGIN][Directory] Add option to order by subscribers 2022-01-01 22:18:18 +00:00
9f11d270f4 [PLUGIN][Directory] Fix opposite sort order 2022-01-01 22:18:18 +00:00
e7940a21ee [PLUGINS][TreeNotes] Feed only shows each note and its respective direct
replies, conversation shows whole tree

[COMPONENTS][Feed] Added request to FormatNoteList event

Every single Note that was provided to FeedController::postProcess is
shown. This means, that even though the Feed is formatted to show only a
Note and its respective direct replies, those same replies are shown
individually again (and they get the chance to show their own direct
replies).

The Note list provided to FormatNoteList is reversed, and for every
index, the respective Note replies are filtered out of the original list.
The replies are then added as leafs of the current Note and added to the tree.
2022-01-01 21:42:47 +00:00
f6311debbf [PLUGIN][Directory] Refactor directory controller, so it's hopefully clearer what's happening 2022-01-01 20:50:04 +00:00
175c98b043 [PLUGIN][Directory] Add options to sort by nickname, created, modified and activity, ascending or descending 2022-01-01 20:49:17 +00:00
acc84d757c [CORE][Controller] Make Controller->{int,bool,string} functions return null if the GET parameter doesn't exist 2022-01-01 20:03:40 +00:00
fc76a00908 [PLUGIN][Directory] Rename actor to people, as it's what's actually interacted with 2022-01-01 20:02:32 +00:00
1f01923aa1 [COMPONENT][Conversation] Implement Conversation muting 2022-01-01 10:32:07 +00:00
1a99762699 [COMPONENT][Posting][Notification] Move group inbox message creation to Notification component 2022-01-01 10:32:07 +00:00
f346cd8167 [COMPONENT][Language][Tag] Update usage of Functional::cartesian_product 2021-12-31 21:03:25 +00:00
7aa90954eb [UTIL][Functional] Update Functional::cartesian_product to pass an array of collections first and a separator after 2021-12-31 21:03:25 +00:00
0050371de7 [PLUGIN][NoteTypeFeedFilter][MediaFeed][COMPONENT][Feed] Rename MediaFeed to NoteTypeFeedFilter and add support for filtering by more types, moving functionality from Feed component 2021-12-31 21:03:25 +00:00
b7872ba4ee [CORE][Controller][FeedController] Use controller instance for filtering, making FeedControler->postProcess function non-static 2021-12-31 21:03:17 +00:00
ba078b7b76 [ENTITY][Note] Caching note replies query
[COMPONENTS][Conversation] Reply route will now present a more suitable title
2021-12-31 17:54:06 +00:00
d7b46735ac [CARDS][Note] Removing unnecessary elements on replies block, and fixing gaps between note-info and the note border itself 2021-12-31 17:02:18 +00:00
6dd31926ad [COMPONENTS][Conversation] reply_add route nows shows the given Note entire conversation, the Note itself is highlighted in the conversation 2021-12-30 18:34:47 +00:00
34cc010136 [CARDS][Note] Separating complementary info as its own block 2021-12-30 18:34:47 +00:00
9a6bdf74dc [COMPONENT][Feed] Add way of filtering the notes on an arbitrary feed with a types GET parameter, that accepts {,!}<[media,text,link,tags]...> 2021-12-30 18:28:57 +00:00
0ae24f6088 [CORE][Controller][FeedController] Use controller instance for filtering, making FeedControler->postProcess function non-static 2021-12-30 18:28:57 +00:00
5f4968ac05 [ENTITY][Note][CACHE] Store lists as lists in the cache 2021-12-30 18:28:57 +00:00
2e0bfc0bcd [TOOLS] Run CS-Fixer on all files 2021-12-30 18:28:57 +00:00
2dbc35fcc3 [DEPENDENCIES] Update dependencies 2021-12-30 18:28:57 +00:00
8831276489 [TOOLS] Fix errors reported by PHPStan 2021-12-30 18:28:57 +00:00
5229d4cd8c [COMPONENT][Notification] Remove nickname GET parameter 2021-12-30 18:28:56 +00:00
cbb70a5054 [COMPONENT][Feed] Refactor Feed component 2021-12-30 18:28:56 +00:00
f16df759a9 [Components][Posting] Posting section title set accordingly if in 'reply_add' route 2021-12-30 16:18:16 +00:00
2c31f2e440 [PLUGIN][Actor Circles] Actor Circles plugin, allow user to create a custom feed of actors 2021-12-30 12:18:16 -03:00
85e31c684d [MODULES][Collection] Fixing mistakes 2021-12-30 12:16:29 -03:00
bdd8cbf36d [COMPONENT][Right Panel] Send request to AppendRightPanelBlock event 2021-12-30 12:14:41 -03:00
d7f70d288d [MODULES][Collection] Abstracting Collections 2021-12-29 21:56:45 -03:00
49d247aec2 [COMPONENTS][Feed] Styling for the empty feed page added 2021-12-29 19:31:28 +00:00
f28ed5e359 [CSS] .note-complementary-info now smaller in general 2021-12-29 19:02:06 +00:00
6b82708968 [CARDS][Note] AppendCardNote event overhaul
[PLUGINS][Favourite] Added complementary information on user action

[COMPONENTS][Conversation] Fixed AppendCardNote issue where cached query
would only act on Notes with depth > 1
2021-12-29 18:47:12 +00:00
836560f55f [CARDS][Note] AppendCardNote event overhaul
[PLUGINS][Favourite] Added complementary information on user action

[COMPONENTS][Conversation] Fixed AppendCardNote issue where cached query
would only act on Notes with depth > 1
2021-12-29 18:35:12 +00:00
0caec6ab9e [COMPONENT][ACTOR CIRCLE] fixing template text 2021-12-29 14:13:25 -03:00
01d5e84a08 [COMPONENT][ACTOR CIRCLE] mention self tag circle with @#self_tag 2021-12-29 14:13:25 -03:00
f9bc1c790f [PLUGIN][AttachmentCollections] Dark mode 2021-12-29 10:52:04 -03:00
25120c6630 [PLUGIN][AttachmentCollections] Responsive pages 2021-12-29 10:52:04 -03:00
137723e59a [PLUGIN][ActivityPub][Favourite][Repeat][Delete] Document event handlers 2021-12-28 22:57:49 +00:00
8274e93ed5 [PLUGINS][DeleteNote] Added documentation, stating the scope of what deleting a Note means 2021-12-28 22:43:04 +00:00
ce3c6a7f23 [PLUGINS][RepeatNote] Added documentation (not for ActivityPub related functions) 2021-12-28 21:51:27 +00:00
846ec37cd9 [COMPONENT][Notification] Add event to decide whether local actors should be bothered 2021-12-28 18:45:18 +00:00
4d8e39bf69 [PLUGIN][RepeatNote] Do not notify about clone note
Fix redirecion after action
Fix typo in activitypub handler
2021-12-28 18:30:27 +00:00
182c6265a3 [PLUGINS][RepeatNote] Add onFilterNoteList event
Filters repeats out of Conversations, and replaces a repeat with the original Note on Actor feed

Added isNoteRepeat to plugin's entity, which returns true if a given
Note is a repeat of another Note
2021-12-28 17:37:01 +00:00
1d1d169a5c [PLUGIN][ActivityPub] Support federation of Tombstones 2021-12-28 17:10:20 +00:00
9cda64f275 [COMPONENT][Notification] Use _m() in reason 2021-12-28 16:36:52 +00:00
3e83387e98 [PLUGIN][DeleteNote] Support ActivityPub 2021-12-28 16:22:38 +00:00
9585472679 [ENTITY][Actor] Basic check if can admin for remote actors 2021-12-28 15:38:41 +00:00
b7c82b9dcb [PLUGIN][DeleteNote] Ensure permissions properly 2021-12-28 15:38:39 +00:00
5c2b46a71d [COMPONENT][Link] Wrap delete operations in transactions 2021-12-28 06:56:05 +00:00
46d121ef7b [COMPONENT][Attachment] Wrap delete operations in transactions and correct sequence of deletation 2021-12-28 06:56:05 +00:00
bf4a0008ef [ENTITY][Note] GNU social uses Tombstones for deleted notes instead of fully removing them.
Various corrections.
2021-12-28 06:56:05 +00:00
bb4149e092 [PLUGIN][AttachmentCollections] Restore functionality
Some minor corrections
2021-12-28 04:43:13 +00:00
a03429ba03 [PLUGIN][DeleteNote] Delete Note action implemented
Replaces Note content with a tombstone, removes any attachment relations and decrements their lives (possibly even removing the attachment), and creates the respective activity
2021-12-27 22:33:36 +00:00
f5b06e2c7e [UTIL][Formatting] Fix group mentions 2021-12-27 21:38:20 +00:00
c40e38c5ba [TOOLS] Fix errors found by PHPStan 2021-12-27 20:37:16 +00:00
d74a9ad373 [ENTITY][Subscription] Add Subscription::cacheKeys 2021-12-27 20:37:16 +00:00
76440961ca [CORE][DB] Add option to findOneBy to return null rather than throw 2021-12-27 20:37:16 +00:00
8796885fa0 [COMPONENT][Tag] Remove '.' from tag regex 2021-12-27 20:37:16 +00:00
5c10448080 [COMPONENT][Group] Add group subscribe button 2021-12-27 20:37:16 +00:00
559ec3df39 [TWIG] Fix login template 2021-12-27 19:09:32 +00:00
20d89f0f24 [COMPONENTS][Avatar] Make sure dimension values are integers
[CARDS][Note] Fix assumed avatar dimension values
2021-12-27 19:08:55 +00:00
19975b8d8d [COMPONENTS][Avatar] Make sure dimension values are integers
[CARDS][Note] Fix assumed avatar dimension values
2021-12-27 19:08:51 +00:00
65a3d738ca [PLUGIN][AttachmentCollections] Make it look good 2021-12-27 15:38:47 -03:00
7ddfe92773 fix: redirect 2021-12-27 15:35:09 -03:00
e932ff43d0 [PLUGIN][AttachmentCollections] changes path name to be the same as the one introduced in c4dacd7626 2021-12-27 15:31:19 -03:00
672df5165c [PLUGIN][AttachmentCollections] Fixing forms submission 2021-12-27 15:25:20 -03:00
72a19d7eac [COMPONENT][Posting] Fix error around mentions of actors that don't exist 2021-12-27 17:35:33 +00:00
b84315c95b [TOOLS] Fix errors reported by PHPStan at level 4 2021-12-27 17:35:33 +00:00
edd996d281 [DEPENDENCIES] Update dependencies, including PHPStan to dev version 2021-12-27 17:35:33 +00:00
cf2f87fc1d [AUTOGENERATED] Update autogenerated code 2021-12-27 17:35:33 +00:00
c9d05d71f5 [COMPONENT][Group] Fix group creation, Refactor related entities to inside the component
Other minor bug fixes and improvements
2021-12-27 17:28:03 +00:00
d03572e366 [PLUGIN][Directory] Make it list groups 2021-12-27 17:10:58 +00:00
de148c1f78 [COMPONENT][Avatar][Controller] Implement multiple dimensions 2021-12-27 05:08:29 +00:00
2a902d6a7e [ASSETS][css][sections] rename profile-avatar to avatar 2021-12-27 05:08:29 +00:00
195618801b [TEMPLATES][Cards][Note] Fix some issues with note minimal 2021-12-27 05:08:29 +00:00
80afc0fa6c [TEMPLATES][Cards][Profile] Provide both actor uri and url, as well as full mention guidance 2021-12-27 05:08:27 +00:00
eb761609aa [ENTITY][Note] If note is a reply to, notify reply's actor 2021-12-27 04:56:00 +00:00
c4dacd7626 [COMPONENT][Attachment] Vinculate note information with attachment controllers
Various minor bug fixes
2021-12-27 04:56:00 +00:00
fd44bc3ac5 [CARDS][Note] Minimize calls between different tables
For instance, the actor_url was set using note.getActor().getUrl() instead of using the actor from the start (since actor was needed in other setters as well).
2021-12-27 03:06:35 +00:00
65676d3980 [CARDS][Note] Fix attachment page from retrieving image dimensions
Attachments may use only a specific block, not the full note macro itself. Since this is the case, the actor needs to be retrieved for the minimal macro note.
2021-12-27 03:06:35 +00:00
ea42ba9f26 [CARDS][Profile] Fix bio
Was using 'hasBio()' instead of 'getBio()'
2021-12-27 03:06:35 +00:00
a1a6f5f4fd [TOOLS] Add warning to update code in bin/generate_entity_fields 2021-12-27 03:06:35 +00:00
93276ce8d0 [AUTOGENERATED] Update autogenerated code 2021-12-27 03:06:30 +00:00
0df423e84b [TOOLS] Update bin/generate_entity_fields so it defaults nullable variables to null and handles null in varchars 2021-12-27 03:03:57 +00:00
7eff22d548 [TOOLS] Fix errors reported by updated PHPStan 2021-12-27 03:03:57 +00:00
52e2231661 [DEPENDENCIES] Update PHPStan and other dependencies 2021-12-27 03:03:57 +00:00
9d3c01312f [CARDS][Note] Fix assumed avatar dimension values 2021-12-27 03:03:53 +00:00
ce23660dba [PLUGIN][ImageEncoder] Only show thumbnails if they exist 2021-12-27 03:02:21 +00:00
58715f1733 [PLUGIN][ImageEncoder] If vips doesn't support, don't throw exception, just let other plugin try 2021-12-27 03:02:20 +00:00
838510ced2 [CARDS][Navigation] Replaced footer to nav
Since the footer is inside a section, it couldn't be a footer element
2021-12-27 03:02:20 +00:00
b30198413c [PLUGINS][Oomox] Add rel to response headers 2021-12-26 21:26:04 +00:00
7402e749cb [COMPONENTS][Feed] Removed unnecessary ARIA 2021-12-26 21:19:33 +00:00
18cfcc0796 [ICONS] Removed XML processing instructions in svg files 2021-12-26 21:19:06 +00:00
045ff6fb68 [PLUGINS][XMPPNotifications] Fix typo 2021-12-26 21:19:06 +00:00
fec1861b80 [CONTROLLER][Note] Respect note scope 2021-12-26 21:19:06 +00:00
d891089945 [PLUGIN][StoreRemoteMedia] Let the user decide the max file size to download 2021-12-26 21:19:04 +00:00
0c421116a6 [ENTITY][Note] Relive isVisibleTo method 2021-12-26 19:50:21 +00:00
78cc9c4659 [PLUGINS][Repeat] Repeat now added has a reply and conversation of original note 2021-12-26 19:16:57 +00:00
e10a38a3e2 [CSS] Align page header on ultrawide screens 2021-12-26 19:16:57 +00:00
feb2631f00 [CARDS][Note] Add permalink to extra note actions 2021-12-26 19:16:57 +00:00
a1d9909379 [CORE][VisibilityScope] Use enum type instead of Bitmap 2021-12-26 19:16:56 +00:00
6f0d9add08 [DEPENDENCIES] Run composer after php version bump from 8.0 to 8.1 2021-12-26 19:16:17 +00:00
6883e51fc8 [DOCKER] Force docker php to use proper PHP executable 2021-12-26 19:16:16 +00:00
3d9141f4ce [COMPONENT][Tag] Allow searching for actor circles with {actor,people}-{circle,list}:#tag 2021-12-26 19:16:16 +00:00
4df80be095 [ENTITY][Actor] Set default null values 2021-12-26 19:16:16 +00:00
d37f38a1ea [ENTITY][Note] A note by default isn't a reply 2021-12-26 19:16:16 +00:00
dd268ba8db [CARDS][Profile] Use Actor::hasBio() instead of getter 2021-12-26 19:16:16 +00:00
8e7c94fe1d [COMPONENT][Attachment] Entity should have default refCount value, every attachment starts with 1 life 2021-12-26 19:16:16 +00:00
94e216a943 [COMPONENT][Conversation] remove early flush in utility function 2021-12-26 19:16:16 +00:00
fdf506b9f9 [CARDS][Note] Fix structure to break content in a controlled manner
[CSS] Responsive feed styling work

Note info content will now break as expected, useless space trimmed down to accomodate smaller screens.
2021-12-26 19:16:16 +00:00
726613cd96 [ENTITY][ActorCircle][COMPONENT][Tag] Add fields to ActorCircle and add or remove target to actor circle when they add or remove a selftag 2021-12-26 19:16:15 +00:00
000ec680e6 [CORE][TOOL] Minor fixes and run cs-fixer 2021-12-26 19:16:15 +00:00
97243151fa [TOOL] CS-fixer does not accept a list of files, so we need to run it on each file individually 2021-12-26 19:16:15 +00:00
c79b1e4c94 [AUTOGENERATED] Update auto generated code 2021-12-26 19:16:15 +00:00
68076d73dd [TOOLS] Update bin/generate_entity_fields so it automatically truncates values in setters 2021-12-26 19:16:15 +00:00
29bb11e8bc [TOOLS] Don't fail commit when checking tools fail 2021-12-26 19:16:15 +00:00
ec28f23025 [TOOLS] Run CS-fixer on all files 2021-12-26 19:16:15 +00:00
5e42723624 [ENTITY][Note] Include reply_to's targets in child's 2021-12-26 19:16:14 +00:00
f5f7fc6056 [PLUGIN][Favourite][Repeat] Add notification target getter 2021-12-26 19:16:14 +00:00
625618b4e0 [PLUGIN][Favourite][Repeat] Fix incorrect use of RedirectException 2021-12-26 19:16:14 +00:00
91f8c86efa [PLUGIN][ActivityPub] Support and federate scopes 2021-12-26 19:16:12 +00:00
21f585ef7e [COMPONENT][Language] Do not exclude notes without language from the feeds 2021-12-26 16:48:36 +00:00
9d5e149dec [COMPONENT][Feed] Correct ordering 2021-12-26 16:48:35 +00:00
19502050e0 [TOOLS] Add remove-file and minor corrections to nuke everything 2021-12-26 16:48:35 +00:00
3e13765f62 [CORE][SCOPE] Implement basic visibility in feeds 2021-12-26 16:48:34 +00:00
d4bc1d097d [ENTITY][NoteTag][COMPONENT][Language] Add language to NoteTag and minor corrections 2021-12-26 06:22:30 +00:00
78fddaf86a [PLUGIN][ActivityPub] Notify mentions in tags 2021-12-26 06:22:28 +00:00
9d0b39e680 [PLUGIN][ActivityPub] Support tags in notes 2021-12-25 18:04:31 +00:00
36483a6ecd [COMPONENT][Link] Ignore html anchors that include mention class 2021-12-25 18:04:30 +00:00
0d5e545a6e [TWIG] Replaced unused markup classes 2021-12-25 17:59:49 +00:00
3275a989db [CSS] Style paging info 2021-12-25 17:48:07 +00:00
ab640b110b [COMPONENTS][Feed] Remove 'feed' from header
When not logged in, the word would be repeated
2021-12-25 17:47:12 +00:00
7891461d36 [PLUGINS][AttachmentCollections] Fix template
[PLUGINS][AttachmentShowRelated] Fix template

[CSS] Fix section-subtitle-details children padding issues

[COMPONENTS][Posting] Remove unnecessary colon

Overall polish of existing plugins templates
2021-12-25 17:31:16 +00:00
ce3b677833 [CONFIG][Twig] Replaced form theme to a custom one
[CARDS][Forms] Added custom social form theme

[CSS] Replaced/added new classes to be used with forms

Base form theme created, can be extended to create complex blocks to be
called by twig when rendering a specific form.
2021-12-25 16:19:46 +00:00
8651bd44c2 [PLUGINS][ProfileColor] Fix callable argument when retrieving cache data 2021-12-25 15:31:24 +00:00
6ada5e60d2 [TOOLS] Make PHP-CS-Fixer and PHP-Doc-check run inside the tooling container 2021-12-25 15:20:21 +00:00
af3d278fde [PLUGIN][AttachmentCollections] Prevent user from appending stuff in a collection (s)he doesn't own 2021-12-25 11:27:00 -03:00
1e965157de [PLUGIN][AttachmentCollections] Iterate documentation 2021-12-25 11:25:50 -03:00
b604ee3146 [COMPONENT][Posting][Tag][Group][Conversation][RightPanel] Rename posting_form.to to posting_form.in, fill in with current group. Refactor context_actor 2021-12-25 11:24:41 +00:00
0f54d2121e [CONTROLLER][Feeds] In Home feed, include specifically subscribed-{person,group,business,organization}, but allow querying for subscribed or subscribed-actor{,s} 2021-12-25 10:12:38 +00:00
dad322e577 [TWIG][Templates] check if variable is defined in twig before using it
fixes error in /actor/X, where there's no page_title defined
2021-12-24 11:44:12 -03:00
de89cffc34 [COMPONENT][Feed] Restrict non-public feeds to logged in users 2021-12-24 14:39:23 +00:00
82e6e95b6a [PLUGIN][AttachmentCollections] Add Attachment Collection plugin which allow users to save attachments in collections 2021-12-24 11:29:37 -03:00
63f9c6341e [COMPONENT][RightPanel] Sends request object in the AppendRightPanelBlock event 2021-12-24 10:20:55 -03:00
1947e99430 [DOC] Add documentation to methods flagged by doc-check 2021-12-24 09:34:13 +00:00
dabf5576d3 [CONTROLLER][Feeds] Implement query for home feed: note-from:subscribed 2021-12-24 09:27:24 +00:00
e3efd25b43 [PLUGIN][ActivityPub] Fix typo in getObjectByUri 2021-12-24 02:46:45 +00:00
7407028891 [PLUGIN][RepeatNote] Fix getRepeatNotes query 2021-12-24 02:46:45 +00:00
10e7c71b6e [COMPONENT][Tag] Do not perform DB::flush in an event 2021-12-24 02:46:45 +00:00
8cd703d68b [COMPONENT][Link] Even if everything else in Posting fails, no reason to discard the finding about the Link 2021-12-24 02:46:45 +00:00
671c3968e2 [TWIG][Templates] Rename inconsistent CSS classes
[CSS] Font size hierarchy refactor
[PLUGINS][MediaFeed] Renamed BeforeFeed event

Type scale hierarchy redone. Bigger line height added, making it easier
to click on links and separate contents.

Feed title added. AddFeedActions replaces BeforeFeed event.
MediaFeed links will now show an icon to the right of the feed title,
smaller footprint and more consistent with the overall design.
2021-12-24 02:46:44 +00:00
f10b3bb05c [PLUGINS][MediaFeed] Fixed template path typos 2021-12-24 02:46:44 +00:00
1e7a285ded [TOOL] Add force-nuke-everything make rule, which deletes the whole database and caches 2021-12-24 02:46:44 +00:00
333e71ed50 [COMPONENT][Group] Add group settings, with support for editing the group's personal info and self tags 2021-12-24 02:46:43 +00:00
a36bdf9719 [UI][I18N] Add missing translation tags in templates/cards/navigation/view.html.twig 2021-12-24 02:46:43 +00:00
69565e3f49 [COMPONENT][Tag] Add missing required route paramter nickname 2021-12-24 02:46:43 +00:00
2e69eac63e [CONTROLLER][UserPanel][UTIL][FORM][ActorForms] Move UserPanel::personalInfo to ActorForms::personalInfo 2021-12-24 02:46:43 +00:00
1e6bc5b6ab [CORE][Form] Fix Form::handle and report back any errors 2021-12-24 02:46:42 +00:00
59abffe744 [ENTITY][Actor][DOC] Add explanation in Actor::__call 2021-12-24 02:46:42 +00:00
be197bc82b [ENTITY][LocalUser] Fix LocalUser::setNicknameSanitizedAndCached so it updates the actor nickname and propagates the exceptions 2021-12-24 02:46:42 +00:00
764a30695d [ENTITY][ActorTag][Actor][Activity] Add Actor::getActorCircles 2021-12-24 02:46:42 +00:00
95783d6109 [CONTROLLER][UserPanel][COMPONENT][Tag] Re-add way of adding self tags, but in a more reusable (and less buggy) way 2021-12-24 02:46:41 +00:00
072caad845 [CONTROLLER][UserPanel] Remove self tags settings from profile settings section, so it can be abstracted and reused 2021-12-24 02:46:41 +00:00
774b33a522 [DEPENDENCIES] Update dependencies and Symfony to 5.4 LTS 2021-12-24 02:46:41 +00:00
80ebd6fb7b [ENTITY][Actor] Add helper function for checking if the current actor can admin another 2021-12-24 02:46:40 +00:00
63679426b6 [UTIL][HTML] Allow <b> and <hr> tags 2021-12-24 02:46:40 +00:00
a28c0da4af [COMPONENT][Language][Settings] Factor out language settings into the language component 2021-12-24 02:46:40 +00:00
2acf0bcbb6 [TEMPLATE][Settings] Factor out settings macros 2021-12-24 02:46:40 +00:00
1682b04e74 [COMPONENT][Group][CONTROLLER][Actor] Move group related stuff to it's own component 2021-12-24 02:46:39 +00:00
67f09d4e50 [CONTROLLER][Actor] Handle case where there isn't a logged in user 2021-12-24 02:46:39 +00:00
4b98200ecd [UI][CARD][Note] Add Conversation link 2021-12-24 02:46:39 +00:00
3c79d82b80 [PLUGIN][ActivityPub][Note] Support inReplyTo 2021-12-24 02:46:39 +00:00
b05106e7f9 [COMPONENT][Conversation] Minor corrections and don't store URI in DB 2021-12-24 02:46:38 +00:00
e04d927fe9 [COMPONENT][Feed][Conversation] Add note-conversation: 2021-12-24 02:46:36 +00:00
17b7ef13a0 [COMPONENT][Conversation] Remove Feed list entry
Notifications feed is enough
2021-12-24 00:47:36 +00:00
e743a17883 [COMPONENT][Notification] Introduce Notifications Feed 2021-12-24 00:47:36 +00:00
2004f1883a [COMPONENT][FreeNetwork] Move feeds that only make sense with FreeNetwork enabled to this component 2021-12-24 00:47:34 +00:00
7d8cce3b27 [COMPONENT][Feed] Correct queries and introduce new feeds
Refactor feeds and search to use a common query builder
2021-12-24 00:44:39 +00:00
1865d2b41e [ActivityPub][Postman] Fill To and CC with mentions 2021-12-24 00:42:02 +00:00
48b2c8c04e [COMPONENTS][Conversation] Local Conversations done
[COMPONENTS][Posting] Call Conversation::assignLocalConversation upon
creating a new note

By using the AddExtraArgsToNoteContent event upon posting a Note, an
extra argument ('reply_to') is added before storing the aforementioned Note.
When storeLocalNote eventually creates the Note, the corresponding
Conversation is assigned.
2021-12-24 00:42:02 +00:00
3ca7a35158 [COMPONENT][Conversation] added onProcessNoteContent event
If the source lacks capability of sending the reply_to metadata, it might be on the note content itself as a reference.

[ENTITY][Note] Documenting conversation/reply related functions. The entity Note reply_to shouldn't be trusted toknow whether or not the Note is a Conversation root. This will happen if a known remote user replies to an unknown remote user - within a known conversation.
2021-12-24 00:42:02 +00:00
c83ae76a68 [COMPONENTS][Conversation] Conversation entity moved to respective component, URI column added
Route for conversation added and Conversation Controller created.

[CONTROLLER][Conversation] Created ConversationShow function, will be used to render the conversation route page

[ENTITY][Note] Conversation id column added, this way a Note can have a direct relation with its respective conversation.
2021-12-24 00:42:01 +00:00
c494928b46 [PLUGIN][MediaFeed] Remove unused import 2021-12-24 00:41:53 +00:00
5115145901 [PLUGIN][MediaFeed] Iterate Documentation 2021-12-24 00:41:44 +00:00
d04b68a3ce [PLUGIN][MediaFeed] Add Media plugin which filters a feed by notes containing media 2021-12-22 11:13:06 +00:00
fb64444325 [UI][CORE][COMPONENT][Search] Refactor templates
Just DRY
2021-12-21 14:38:58 -03:00
dd5d46c556 [CORE] Add option to filter notes even when there's no actor 2021-12-21 14:33:19 -03:00
ce91826d31 [CORE][UI] Added the possibility to draw stuff before feed starts 2021-12-21 14:29:05 -03:00
012e0665b0 [COMPONENT][Search] Only display search subscribe field if a user is logged in 2021-12-21 16:45:59 +00:00
af122df6e1 [CONTROLLER][Actor] Fix actor view route 2021-12-21 16:45:59 +00:00
8b5286c383 [COMPONENT][Notification] Do not re-render content just to grab attentions
Other minor improvements and bug fixes
2021-12-21 16:05:24 +00:00
e2c0505620 [ActivityPub][Inbox] Add request to debug logs 2021-12-21 15:52:41 +00:00
e7dcea3f26 [CONTROLLER][Actor] Add group notes query and fixup template 2021-12-21 12:47:16 +00:00
6a8144003f [ENTITY][Actor] Add missing 'break' statements in switches in getUr{i,l} 2021-12-21 12:46:42 +00:00
25900d38bd [UTIL][EXCEPTION][RedirectException] Remove hack that would attempt to generate a URL inplace 2021-12-21 12:46:02 +00:00
027adc97b2 [CONTROLLER][ActorController] Make ActorController extend the FeedController, so notes get filtered 2021-12-21 12:45:15 +00:00
7f65b23074 [DB] Allow mentioning 'note' in a DQL query (in quotes), in order to be able to search in the activity table (previously would be replaced by the class name) 2021-12-21 12:44:34 +00:00
85735222cb [COMPONENT][Posting] When a group is mentioned, add that note to the group inbox 2021-12-21 12:43:28 +00:00
d6d5926b6e [TOOLS][DOC] Add missing documentation, as flagged by doc-check 2021-12-21 12:24:23 +00:00
da8c41e094 [TOOLS] Fix errors found by PHPStan 2021-12-21 12:17:51 +00:00
fa863d9e03 [CONTROLLER][ENTITY][Actor] Add way of creating a group that doesn't exist 2021-12-21 12:12:03 +00:00
88a137fb15 [ROUTES] Rename actor routes and add route for groups 2021-12-21 12:10:51 +00:00
87aa9360a3 [CORE][ActorController] Refactor actor related controllers (Actor, Subscribers, Subscriptions) to remove duplicated code 2021-12-21 12:10:08 +00:00
315fd95b94 [COMPONENT][Posting] Add facility to allow mentioning groups that don't yet exist 2021-12-21 12:07:54 +00:00
36976d8fe7 [DOCKER] Update configuration script to include the worker container 2021-12-20 20:39:54 +00:00
e27f2dd202 [ENTITY] Remove Group entity, as groups are actors 2021-12-20 20:20:25 +00:00
918e6823a9 [ENTITY][Actor] Init Actor's class variable homepage, bio, and location to null
The template cards/profile/view.html.twig tries to access the bio variable before it's initialized, an is null check was already in place. However, even then, the variable needs to be init beforehand. The same change was applied to homepage and location since they might lead to similar issues.
2021-12-20 16:31:26 +00:00
622057ba0d [CONTROLLER][Feeds] Added should_format field on returned array
FeedController will only handle FormatNoteList if the should_format field is true.

This change was made to make the replies route feed possible, this route is added by the Conversation component. Since a reply isn't a conversation root, if the FeedController handled the FormatNoteList event, this feed wouldn't have any notes to display.
2021-12-20 15:39:23 +00:00
23f94ac961 [CORE][Controller] Define html format as default 2021-12-20 13:32:49 +00:00
1832397363 [ActivityPub] Include recent actor type attribute in its creation
Improve debug logs
2021-12-20 13:32:49 +00:00
ed67da89dc [TAGS] Fix some minor logic issues with Actor Tags and Circles 2021-12-20 13:32:49 +00:00
a9feb79825 [SECURITY] New actors are Person user on register by default 2021-12-20 13:32:49 +00:00
630e22579e [PLUGIN][RepeatNote] Add support for onGSVerbToActivityStreamsTwoActivityType 2021-12-20 13:32:48 +00:00
8d1e000574 [PLUGIN][Favourite] Add support for onGSVerbToActivityStreamsTwoActivityType 2021-12-20 13:32:48 +00:00
a9c73a8f33 [PLUGIN][ActivityPub] Add mention tags 2021-12-20 13:32:48 +00:00
a005a7bcea [PLUGIN][ActivityPub] Add getUriByObject, so that we can construct activities referring to other known objects (local or foreign) 2021-12-20 13:32:46 +00:00
57beb178cc [Notification][ENTITY][Activity] Avoid including sender in notification targets 2021-12-19 19:04:05 +00:00
93fa7eb0b5 [ENTITY][Note] Language in notes is optional 2021-12-19 19:04:05 +00:00
1d09a02ad6 [FreeNetwork][ActivityPub] Sometimes remote Actors report empty full names in not very explicit manners 2021-12-19 19:04:05 +00:00
a81ac673ac [CORE][ENTITY] Rename 'Entity::getWithPK' to 'Entity::getByPK' 2021-12-19 19:04:01 +00:00
330b6b49a2 [COMPONENT][Posting] Add support for posting with empty content. At least one of content and attachments must be provided 2021-12-16 11:08:53 +00:00
5dca5568b7 [CORE][Cache] Fix wrong return type in Cache::delete 2021-12-16 11:01:23 +00:00
1b45fb251a [COMPONENT][Search][Attachment][DOC] Add doocumentation to search related functions 2021-12-16 10:52:06 +00:00
24291a268a [CORE][Cache][DOCS] Add documentation to complex private function 'Cache::redisMaybeRecompute' 2021-12-16 10:47:01 +00:00
b0d5ce8aab [COMPONENT][Search] Don't explode if provided an empty search query 2021-12-16 10:41:29 +00:00
a16d31b70e [COMPONENT][Search] Add support for searching in notes' contents 2021-12-16 10:39:36 +00:00
060c3f01a6 [CACHE][CONFIG] Disable early recompute by default 2021-12-13 15:49:53 +00:00
6d8679d86b [CORE] Fix resetting the config to the default values 2021-12-13 15:49:52 +00:00
ff38efd5f1 [PLUGIN][ProfileColor] Cache results 2021-12-13 15:49:52 +00:00
3ba7e1804b [CORE][Cache] Add fast path for redis cache interactions 2021-12-13 15:49:52 +00:00
10ddbf692a [ENTITY][LocalUser] Make more use of caching and factor out the cache keys 2021-12-12 16:21:09 +00:00
f6a8ee86b6 [COMPONENT][Search] Add support for searching for a given actor type 2021-12-11 22:21:31 +00:00
4be226edd5 [COMPONENT][Search] Make search title field not required 2021-12-11 22:20:25 +00:00
1e8eea0434 [ENTITY][Actor] Add type field, which denotes whether the actor is a person, org, group, business or bot 2021-12-11 22:19:37 +00:00
e62896b84e [UTIL][FormFields] Allow specifying a null actor in the language field, for when there isn't a logged in user 2021-12-11 22:18:31 +00:00
6b38972cca [COMPONENT][Search] Add support for searching for notes with media or with text
`note-types:media` will search for notes with an associated attachment or no text
2021-12-11 20:59:13 +00:00
bad5efe819 [COMPONENT][Search] Be explicit about including : 2021-12-11 20:56:47 +00:00
01470ee664 [COMPONENT][Search] Add facility for supporting searching for note types 2021-12-11 19:33:30 +00:00
d667c3a453 [COMPONENTS][Search][UI] Add options to filter by note or actor type. Reorganize UI 2021-12-11 17:48:40 +00:00
e8ddca6b06 [COMPONENT][LeftPanel] Add previous title to error message when a duplicate feed is found 2021-12-11 16:50:52 +00:00
682f9aa611 [COMPONENT][LeftPanel] Ensure given url corresponds to a feed 2021-12-11 10:50:29 +00:00
dbc8bf2ae1 [COMPONENT][Search][LeftPanel] Add way of adding a search result as a left panel feed 2021-12-11 10:49:57 +00:00
9afe6ecfac [COMPONENT][Search] Add search query builder 2021-12-10 21:19:21 +00:00
fceb014606 [COMPONENT][Language] Add support for searching for multiple languages at the same time 2021-12-10 21:15:12 +00:00
6a9388a789 [UTIL][FormFields] Add option language form field so the user can provide no selection 2021-12-10 21:03:37 +00:00
ab5e074d9e [DEPENDENCIES] Update lstrojny/functional-php 2021-12-10 13:54:10 +00:00
ada94a98e2 [COMPONENT][Search] Move search form to utility function. Add search form and search builder forms to search results page 2021-12-10 13:53:23 +00:00
8beb9682ee [COMPONENTS][Search][Language] Move language search features to the language component. Add support for searching for notes from people with a given language 2021-12-10 13:53:23 +00:00
c720ce7daf [UTIL][Functional] Add cartesianProduct while it doesn't get merged upstream to \Functional 2021-12-10 13:53:23 +00:00
dd33720957 [TWIG] Add 'dd' and 'die' functions to twig 2021-12-10 12:06:47 +00:00
33fba0d970 [COMPONENT][Language][ENTITY][ActorLanguage] Refactor cache keys in ActorLanguage. Add ActorLangauge::getActorRelatedLanguagesIds and use it in note filtering in the Language component 2021-12-10 10:19:23 +00:00
5dd9e5a3d7 [PLUGIN][RepeatNote] Add Notifications and ActivityPub support
Minor bug fixes
2021-12-10 04:05:41 +00:00
0ee4cc7709 [PLUGIN][Favourite] Notify when actor favours a note 2021-12-10 04:05:35 +00:00
60d31e097e [COMPONENT][Notification] Support empty array of targets 2021-12-10 04:05:34 +00:00
b89f57ce93 [ENTITY][Note] Language can be null 2021-12-10 04:05:34 +00:00
4992ff153b [PLUGIN][RepeatNote] Fill activity log and fix some bugs
Refactored the plugin.
2021-12-10 04:05:26 +00:00
01689edc66 [PLUGIN][Favourite] Report already favoured or unfavoured 2021-12-10 04:05:22 +00:00
0c11fe413c [COMPONENT][Tag] We don't always have information about if a tag is canonical 2021-12-10 04:05:22 +00:00
dcc37b055d [COMPONENT][Link] Remove relation to note when note is removed
Moved entity NoteToLink to the component
2021-12-10 04:04:56 +00:00
dcc867dad7 [COMPONENT][Attachment] Delete related 2021-12-10 02:46:25 +00:00
5f167517ad [ENTITY][Note] Add deleter 2021-12-10 02:46:25 +00:00
b1585f0ef2 [ENTITY][Actor][ActorTag] Ensure only one copy of each tag is inserted 2021-12-09 22:23:17 +00:00
45d1ca88a6 [COMPONENT][Tag] Ensure only one copy of each tag is inserted 2021-12-09 22:22:31 +00:00
ab9dd1db77 [CACHE][ENTITY][Actor] Refactor Actor so that all cache keys are kept in one cacheKeys function, so that we can more easily be certain there are no mismatches in cache keys between gets and deletes 2021-12-09 21:59:49 +00:00
4d2230ff43 [COMPONENT][Language] Add Language component and implement language based note filtering 2021-12-09 21:39:00 +00:00
1be4b3d481 [EVENT][FilterNoteList] Use an in-out parameter, so multiple events can act on this 2021-12-09 21:39:00 +00:00
3405312a5b [COMPONENT][Search] Add way of searching for only notes or poeple with a given language 2021-12-09 21:39:00 +00:00
f547fd3bb9 [CONTROLLER][FeedController] Fix return value, from notes to notes_out 2021-12-09 19:06:18 +00:00
c137a484af [ENTITY][ActorTag] Fix url in actor tag 2021-12-09 16:34:07 +00:00
26b95fae96 [PLUGIN][StemWord] Remove the country part from the code. Ignore if no stemmer is found for the given language 2021-12-09 16:23:09 +00:00
659ea5cd1f [COMPONENT][Search] Use correct template for displaying actors 2021-12-09 16:23:09 +00:00
bc3e6ac704 [COMPONENT][Search] Fix searching for actors 2021-12-09 16:23:09 +00:00
139da2c07f [COMPONENT][Search][Tag] Add support for searching for actors or notes with a language. Use leftJoins, rather than inner joins 2021-12-09 16:22:59 +00:00
774e32f834 [PLUGINS][TreeNotes] Working, however feed is still not formatted
[ENTITY][Note] Fix for getReplies()
2021-12-09 00:15:47 +00:00
64122a9612 [PLUGIN][Favourite] Add ActivityPub Inbox support 2021-12-08 23:24:25 +00:00
5025901c86 [PLUGIN][Favourite] Log changes into Activity 2021-12-08 23:24:25 +00:00
480a42cca5 [PLUGIN][ActivityPub] Introduce ActivitypubObject. Beware, inside the plugin, an Object can never be an Activity.
Many bug fixes and other major changes (interface changed, see EVENTS.md)
2021-12-08 23:24:23 +00:00
b1227d36f1 [CARDS][Note] In conversation time ago information added 2021-12-08 22:48:04 +00:00
df92b0d225 [COMPONENTS][Conversation] Refactored Reply plugin into Conversation component
[PLUGIN][TreeNotes] TODO: think it is broken, perhaps a problem of the conversation arguments passed in note card template
2021-12-08 22:48:04 +00:00
e9dfa0f08c [COMPONENT][Attachment][Posting] Move onHashFile from Posting to Attachment. Remove onGetAllowedThumbnailSizes 2021-12-08 20:42:29 +00:00
614e02b4c6 [PLUGIN][TagBasedFiltering] Add to user settings page and split adding tags from note/actor from editing blocked 2021-12-08 19:57:36 +00:00
d52a043705 [TWIG] Restructure user settings template, making it much easier to use and extend 2021-12-08 19:57:35 +00:00
6627006e61 [COMPONENT][Avatar] Move avatar settings template from core to component 2021-12-08 19:57:29 +00:00
870f866c23 [CARDS][Navigation] Section styling more consistent and can now be selectively hidden by user
[COMPONENTS][Right] Changed additional options div class names
2021-12-08 15:16:30 +00:00
a285128dab [COMPONENTS][Posting] Added language help text
[COMPONENTS][Tag] Added Posting form canonical tags field help text
2021-12-08 14:28:58 +00:00
a4f18b937e [CSS] Forced to re-add webkit mask image prefix for checkbox styling 2021-12-08 13:44:06 +00:00
3b8a3e953d [CONTROLLER][FeedController] Make post processing happen more automatically, reducing noise in individual controllers. Now it's enough to simply extends App\Core\Controller\FeedController, to implement a feed 2021-12-08 10:20:37 +00:00
7783922b2e [CONTROLLER][PLUGIN][Directory][Favourite][Reply][CORE][FeedController] Refactor to new FeedController 2021-12-07 23:34:32 +00:00
ba87944732 [COMPONENT][CONTROLLER][Search][CORE][FeedController] Use new FeedController base class 2021-12-07 21:07:37 +00:00
4c0210fb00 [CORE][FeedController][CONTROLLER][Feeds] Refactor feed filtering into base class 2021-12-07 21:06:39 +00:00
b8e9c2ce41 [COMPONENT][Search] Add title so it's clearer these are search results 2021-12-07 20:36:25 +00:00
f9fedfb131 [COMPONENT][Search] Fix search 2021-12-07 20:26:39 +00:00
c131e47176 [COMPONENT][Tag] Remove wrong canonicalization of tags in tag feed controller. Fix display of original tags 2021-12-07 20:10:59 +00:00
c093eb9089 [TWIG] Update instanceof filter to be able to check for native types 2021-12-07 19:52:27 +00:00
26a324ee4b [TWIG][Templates] Sort languages settings template polish 2021-12-07 18:46:58 +00:00
c21d4d1811 [CSS] Added webkit required vendor specific prefix for mask image 2021-12-07 18:46:07 +00:00
b0fea51251 [TWIG][Templates] Clearer visual feedback that a note is a reply 2021-12-07 16:17:49 +00:00
4657a1d6a5 [COMPONENTS][Tag] Fix actor tag template
[PLUGINS][RelatedTags] Fix actor tag template
2021-12-07 15:35:27 +00:00
0bac6a229e [COMPONENTS][RightPanel] Added 'Additional options' details on posting form
[CSS] Trimming down wasted space and vendor related prefixes

[TWIG][Templates] Added main navigation to navigation card, removed note car language short display
2021-12-07 15:33:02 +00:00
92314403bb [CSS] Preventing note actions extra from overflowing 2021-12-06 23:38:38 +00:00
546c5c84fd [COMPONENTS][Tag] Actor/Note tag template polished
[PLUGINS][RelatedTags] Disable rendering of template when no results are found
2021-12-06 22:22:23 +00:00
ef435b824b [CSS] You can hide Posting section on command now 2021-12-06 21:07:45 +00:00
a6af3a9b7a [CSS] Removed unnecessary box-shadow rules that slowed down performance (see edit feeds page) 2021-12-06 20:56:06 +00:00
cd607ce6ce [CSS] Note actions extra line height removed, margin-bottom used instead
[CSS] Anchors use underline again on hover
2021-12-06 20:47:56 +00:00
6303f480f7 [TWIG] Note actions extra structural changes to reflect standard note actions styling
[CSS] Note actions extra details styling done
2021-12-06 20:35:44 +00:00
cb276aee81 [CSS] Screen media queries are now clearly documented and calculated using various takes on the Van de Graaf Canon and Tschichold’s recommended 2:3 page-size ratio 2021-12-06 19:07:59 +00:00
330e09f2d3 [PLUGIN][ActivityPub] Only store a new object if there were no previous activities with it before 2021-12-05 21:09:30 +00:00
5196b669b9 [PLUGIN][ActivityPub] Add attachment support to Notes 2021-12-05 21:04:20 +00:00
63bf93d7f3 [CORE][Entity][Note] Language can be null 2021-12-05 21:03:13 +00:00
19b8a7648e [PLUGIN][ActivityPub] Implement Avatar support 2021-12-05 20:08:14 +00:00
2a161c9c66 [PLUGIN][TagBasedFiltering] Block actor tags, but don't block notes from the current actor 2021-12-05 19:18:57 +00:00
259e07b259 [ENTITY][ActorTag][ActorTagBlock] Add 'use_canonical' column 2021-12-05 17:55:49 +00:00
9f445632b2 [PLUGIN][TagBasedFiltering] Expand to allow filtering by actor tags 2021-12-05 17:55:49 +00:00
e29e1cc87c [ENTITY] Rename 'getFrom' to 'getBy' 2021-12-05 17:55:46 +00:00
c40866ecf6 [PLUGIN][TagBasedFiltering] Add TagBasedFiltering plugin, which allows filtering feeds by note tags and (soon) actor tags 2021-12-05 17:54:58 +00:00
4f669d4e01 [ENTITY][NoteTag][Language] Add convinience cache getters 2021-12-05 17:54:58 +00:00
a47a01abee [ENTITY][ActorTagBlock][NoteTagBlock] Add ActorTagBlock and NoteTagBlock 2021-12-05 17:54:58 +00:00
6b719daa14 FIXUP POSTING TAG COMP 2021-12-05 17:54:58 +00:00
8a495bd714 [CONTROLLER][Feeds][EVENT] Refactor and add 'FilterNoteList' event 2021-12-05 17:54:58 +00:00
2f5bde913c [COMPONENT][Posting][Tag] Add mechanism for adding extra fields to and handling the data from the Posting form. Add 'use canonical tag' field 2021-12-05 17:54:58 +00:00
314859b775 [ENTITY][NoteTag] Add 'use_canonical' column, which indicates whether the user wanted to canonicalize the tag or not (for themselves, the canonical field is still filled, for blocks) 2021-12-05 17:54:58 +00:00
1457aa8220 [UI][PLUGIN][DeleteNote][EVENT] Add 'AddExtraNoteActions' event, which can be leveraged to add extra actions on each note, but which are normally collapsed 2021-12-05 17:54:58 +00:00
969df371dd [COMPONENT][Avatar] Small refactor 2021-12-05 17:54:58 +00:00
9512890264 [PLUGIN][ActivityPub] Implement Actor Update
Diverse minor bug fixes
2021-12-05 03:11:08 +00:00
9506909e7a [COMPONENT][FreeNetwork] Iterate documentation 2021-12-04 21:05:09 +00:00
778cb57d83 [PLUGIN][ActivityPub] Finish base ActivityStreams 2.0 interface
Instructions below

To extend an Activity properties do:

public function onActivityPubValidateActivityStreamsTwoData(string $type_name, array &$validators): bool {
    if ($type_name === '{Type}') {
        $validators['attribute'] = myValidator::class;
    }
    return Event::next;
}

The Validator should be of the form:

use ActivityPhp\Type;
use ActivityPhp\Type\Util;
use Plugin\ActivityPub\Util\ModelValidator;

class myValidator extends ModelValidator
{
    /**
     * Validate Attribute's value
     *
     * @param mixed $value from JSON's attribute
     * @param mixed $container A {Type}
     * @return bool
     * @throws Exception
     */
    public function validate($value, $container): bool
    {
        // Validate that container is a {Type}
        Util::subclassOf($container, Type\Extended\Object\{Type}::class, true);

        return {Validation Result};

To act on received activities do:

public function onActivityPubNew{Type}(&$obj): bool {

To add information to Activities being federated by ActivityPub do:

public function ActivityPubAddActivityStreamsTwoData(string $type_name, &$type): bool {

To implement an ActivityStreams 2.0 representation do:

public function onActivityPubActivityStreamsTwoResponse(string $route, arrray $vars, ?TypeResponse &$response = null): bool {
        if ($route === '{Object route}') {
                $response = ModelResponse::handle($vars[{Object}]);
                return Event::stop;
        }
        return Event::next;
}
2021-12-04 21:05:07 +00:00
044649c745 [PLUGIN][VideoEncoder] Some videos don't have images (video stream), only audio, handle that 2021-12-03 03:32:44 +00:00
4501b7e85e [CONTROLLER][UserPanel] Re-organised all settings forms. Added email, password, language forms separated from account or personal account info
[CORE][Form] Better PHPDoc and used is_null() for checks

[ENTITY][LocalUser] Add setNicknameSanitisedAndCached

[UTIL][Exception] Better NicknameNotAllowedException default message
2021-12-03 03:32:43 +00:00
e16fade490 [CONFIGURATION] Add webp to attachments:supported whitelist 2021-12-03 03:32:43 +00:00
582519e13e [COMPONENT][Attachment] Do not show download links for non-local attachments 2021-12-03 03:32:43 +00:00
ff5f346fec [PLUGINS][Oomox] Further checks done when handling form requests. Improved documentation, fixed typos and diminished repeated calls 2021-12-03 03:32:38 +00:00
ba632b4514 [CSS] Note content text decoration underline set on anchor links 2021-12-03 01:19:09 +00:00
b66873e289 [PLUGIN][StoreRemoteMedia] Do not save empty files 2021-12-03 01:16:57 +00:00
70ed04a7db [COMPONENT][Link] Fix some minor issues with empty headed links, typo in event handler's name, and refactor entity to inside component 2021-12-03 00:46:52 +00:00
56d653d980 [CSS] Adding margin-left to .note-author-nickname 2021-12-02 22:55:01 +00:00
bded039282 [PLUGIN][Embed] try catch absence of favicon 2021-12-02 22:49:27 +00:00
d802af6d91 [COMPONENTS] Accesskey highlight class set 2021-12-02 22:44:58 +00:00
a1b002659f [CSS] Focusable elements only show accent inset shadow when focused by keyboard, not by any other way 2021-12-02 22:40:27 +00:00
2e11001b8f [PLUGIN][Embed] Fix links 2021-12-02 22:21:49 +00:00
e5f09a26d4 [CSS] Ultra widescreen dimensions fix 2021-12-02 22:21:49 +00:00
6ce78141a8 [CONTROLLER][UserPanel] Actor nickname cache is updated 2021-12-02 22:21:47 +00:00
5130e7e70f [COMPONENT][Attachment] Update routes to use /object/ namespace 2021-12-02 21:26:06 +00:00
2445b5318d [PLUGIN][Embed] Make it work when content-length header is not provided 2021-12-02 21:26:06 +00:00
bfec10fc95 [COMPONENT][Attachment][Entity][Attachment] getThumbnail can be null 2021-12-02 21:26:05 +00:00
2967b544f5 [CONTROLLER][UserPanel] Nickname now normalized 2021-12-02 20:49:10 +00:00
12557a1e16 [PLUGINS][Oomox] Reset theme colors added 2021-12-02 20:26:27 +00:00
863cfbdedc [CONTROLLER] Old password input type set to password
[CONTROLLER] Notification form fields requirement set to false
2021-12-02 19:32:39 +00:00
f5ec099e9a [COMPONENT][Tag][Search] Fix typo in event handler name mismatch 2021-12-02 19:17:37 +00:00
772ec6efcf [UI] Set html img width and height attributes for avatar 2021-12-02 19:13:33 +00:00
92d5f3ec1e [COMPONENTS][Avatar] Delete correct cache key on avatar update 2021-12-02 19:13:23 +00:00
d915b4b628 [CSS] Note language note view polish 2021-12-02 18:36:18 +00:00
f35dbbd8c1 [COMPONENTS][Search] Polished template
[COMPONENTS][Search] Fix event typo
2021-12-02 16:37:17 +00:00
5cd96669fd [COMPONENTS] LeftPanel and RightPanel checkbox hack trick
The anchor used for the accessibility menu preceded the left/right panel sections, rendering the checkbox useless
2021-12-02 15:49:09 +00:00
9482bb2254 [CSS] Avatar max-height defined 2021-12-02 15:30:24 +00:00
eeaad19754 [Attachment] Move Controller and Entities to a Component
There's no problem in having the templates in the core
2021-12-02 15:14:07 +00:00
37ef8cddfa [ENTITY][Note] Add getLanguageLocale() and getNoteLanguageShortDisplay()
[CARDS][Note] Render note's language short display

[PLUGINS] Bring back titles to Reply, Repeat and Favourite actions
2021-12-02 15:05:49 +00:00
d044039272 [FreeNetwork] Initial multi-protocol support 2021-12-02 14:23:21 +00:00
dbaee08038 [FreeNetwork] Move mentions logic from AP to FN and handle local webfinger mentions properly 2021-12-02 11:12:04 +00:00
53c46127c1 [ActivityPub][Explorer] Store remote's url properly 2021-12-02 11:12:03 +00:00
30f3e2c462 [FEEDS][Home] Fix bug nickname is not unique, but it is for local users 2021-12-02 11:12:03 +00:00
d64bd17422 [COMPONENTS][LeftPanel] Fix template filename 2021-12-01 22:19:00 +00:00
eeb42ef8ea [CONTROLLER][Actor] Provide template with all notes by actor
[ENTITY][Note] Add getAllNotesByActor

[TWIG] Actor profile page now renders all notes by the actor
2021-12-01 21:41:41 +00:00
6bcd42a3a7 [TWIG][Base] Remove user has to be logged in condition when rendering right panel. 2021-12-01 21:15:31 +00:00
5d8bd6c74a [TWIG][Note] Add single note view 2021-12-01 21:07:14 +00:00
6f543ccc06 [ActivityPub][Model][Activity] Translate including objects 2021-12-01 20:53:51 +00:00
e7ee558f4a [TWIG] Fix empty accessibility menu anchor, accesskey anchors placement
[CSS] Dark theme hover/focus border, settings page form visibility
2021-12-01 20:29:11 +00:00
030c966b74 [DOCKER][Accessibility] Add pa11y docker image for automated accessibility tests
TODO: Testing within local social container
2021-12-01 20:29:06 +00:00
dcbb3488c4 [PLUGINS][Reply] Fix onAppendCardNote return 2021-12-01 19:47:45 +00:00
fa7fa81e35 [ICONS][Edit] Add icon class twig block
[CSS] Move edit feed link aligment rules to base.css
2021-12-01 19:47:45 +00:00
4155926ebf [CSS] Removing arbitrary unit values 2021-12-01 19:47:44 +00:00
db0909a1c7 [CSS] Fix color swatch styling, simplified rules 2021-12-01 19:47:44 +00:00
74bab8e7aa [COMPONENTS][Left][CONTROLLER][EditFeeds] Add missing action and method to <form> 2021-12-01 19:47:44 +00:00
b7fe924bdd [TOOLS][DOCS] Add missing doc blocks, as signaled by doc-checker 2021-12-01 19:47:44 +00:00
d58483a6ca [TOOLS] Cleanup PHPStan warnings 2021-12-01 19:47:43 +00:00
0b57b20d38 [UI][PLUGIN][Reply][Favourite][ENTITY][Feed] Remove replies and favourite links from navigation/view.html.twig and add them to the feeds section 2021-12-01 19:47:43 +00:00
36613a826d [CONTROLLER][PLUGIN][Reply] Move reply controller to it's plugin 2021-12-01 19:47:43 +00:00
73981030fa [CONTROLLER][COMPONENT][Left] Move edit feeds controller to the Left component 2021-12-01 19:47:43 +00:00
475bb1a033 [UTIL][EXCEPTION][BugFoundException] Use only the relative path, for convenience and to avoid potentially leaking the sysadmin's user 2021-12-01 19:47:42 +00:00
d4c77925d2 [CORE][DB][ENTITY][Actor] Make DB::dql return a chunked array if selecting multiple entities, remove partitioning from callsite
`DB::dql('select a, b, from a join b')` would previously return `[a,
b, a, b, ...]` (or even `[b, a, b, a, ...]`), and now will return
`[[a, a, ...], [b, b, ...]]`. The issue would be further compounded
when selecting even more entities, where the order would be
unpredictable
2021-12-01 19:47:42 +00:00
6c7f69dd94 [ENTITY][Actor] Partition the results of the joint query into a separate list of ActorsCircles and ActorTags, as desired 2021-12-01 19:47:42 +00:00
a3e5f7646c [CONTROLLER][UserPanel] Use only the ActorTags in the settings 2021-12-01 19:47:42 +00:00
3fbd2cd2b9 [PLUGIN][RelatedTags] Remove duplicate results 2021-12-01 19:47:41 +00:00
4f7e243bee [CORE][DB] Don't do column renaming if a list of entities is specified 2021-12-01 19:47:41 +00:00
ed5f6b6eed [COMPONENTS][Search][UI] Use base template and macros to display search results 2021-12-01 19:47:41 +00:00
424df54a1b [ActivityPub] Add HTTP Signatures 2021-12-01 19:47:41 +00:00
123544fa50 [ActivityPub] Port Postman 2021-12-01 19:47:40 +00:00
df3fbbc9e7 [ActivityPub] Add ActivityToType
Minor bug fixes
2021-12-01 19:47:39 +00:00
4ddd00a091 [NOTIFICATION] Add FreeNetwork distribution 2021-11-30 00:48:46 +00:00
84217ec866 [CSS] Fix multiple select box styling 2021-11-29 23:12:10 +00:00
f92c00c7aa [CONTROLLER][Feeds] Add block prefixes to distinguish form groups
[TWIG] Divide form into various groupings for clearer representation
2021-11-29 23:12:09 +00:00
c8ba81897c [PLUGINS][Reply] getReplyToNote performance improvement
[CSS] Replies padding fix
2021-11-29 23:12:09 +00:00
01078e20fb [PLUGINS][Reply] Fix return on getReplyToNote
The array contained an object, the result was within that object and not the object itself.
2021-11-29 23:12:09 +00:00
db33800ade [PLUGINS][Reply] Array key 'reply_to' checked if it exists.
Plugin\Reply\Entity\NoteReply::getReplyToNote lacked a check to make sure the 'reply_to' key existed within the array resulting from the query.
2021-11-29 23:12:09 +00:00
98568b6f53 [ENTITY][Actor][ActorTag] Make Actor->getSelfTags and Actor->getOtherTags return [ActorCircle[], ActorTag[]], rather than ActorCrircle alone 2021-11-29 23:12:07 +00:00
3477ad5efc [PLUGINS][RelatedTags] Add related tags plugin and needed infrastructure. Initial work on pinned content 2021-11-29 22:42:51 +00:00
3227018963 [CORE][DB] Allow specifying the entites to be retrieved, as when using renaming, tables in join would attempt to be selected 2021-11-29 22:42:50 +00:00
5c3d561a67 [COMPONENTS][Tag] Refactor Tag and add self tag stream 2021-11-29 22:42:50 +00:00
6680772e47 [UI][I18N][UTIL][FormFields][Language][COMPONENTS][Posting][PLUGINS][Reply] Factor out translation from FormFields::language and remove help text in cases from Posting and Reply 2021-11-29 22:42:50 +00:00
fc81f7301c [CORE][DB][ENTITY][Actor] Add DB::removeBy and use it in Actor->setSelfTags 2021-11-29 22:42:50 +00:00
66ff3c594d [UTIL][Formatting] Fix wrong event name 2021-11-29 22:42:49 +00:00
8f5b404941 [CACHE] Switch to 'empty' rather than 'is_null' is Cache::getHashMapKey, as it may return null or false 2021-11-29 22:42:49 +00:00
f986f59424 [ENTITY][ActorTag] Add 'canonical' field to actor_tag 2021-11-29 22:42:49 +00:00
798a5f3796 [PLUGINS][Oomox] HTML's input[type='color'] doesn't support alpha values. Feature to apply custom shadow color removed as a result. 2021-11-29 22:42:48 +00:00
7df2783686 [CSS] Fixed edit feed icon styling. 2021-11-29 22:42:48 +00:00
6ec0b9f077 [CSS] User panel CSS fixes.
[PLUGINS][Oomox] Reformatted file.
2021-11-29 22:42:48 +00:00
04257c5fd9 [PLUGINS][Oomox] Resulting forms are now aware of user defined colours and fallback to defaults. 2021-11-29 22:42:48 +00:00
3da524af58 [PLUGINS][Oomox] WIP Settings for both the light and dark themes. 2021-11-29 22:42:47 +00:00
56526c9ba6 [ActivityPub][Inbox] Restore Create Note Functionality
Minor bug fixes
2021-11-29 22:42:46 +00:00
7145dba8af [PLUGINS][Oomox] getEntity added.
[CORE][Cache] exists added.
2021-11-27 15:14:17 +00:00
7b9d388a44 [NOTIFICATION] Implement Target Collector 2021-11-27 15:14:15 +00:00
51994406da [CORE][ENTITY] Properly port ProfileTag, ProfileTagSubscription and ProfileList as ActorTag, ActorTagSubscription and ActorCircle 2021-11-27 04:17:18 +00:00
11d2cfb9ed [UI][FEEDS][ENTITY][Feed] Add way to customize the feeds that are displayed in the left panel. The user can add, delete, reoder and rename them 2021-11-26 23:35:10 +00:00
cdc8886bb8 [CORE][DB] Rename parameters 'orderBy' to 'order_by' 2021-11-26 23:34:37 +00:00
42f40f9ebe [CORE][CONTROLLER][Network] Refactor term 'network' into 'feeds' 2021-11-26 23:34:37 +00:00
0ab8febab3 [CORE][DB] Document magic methods 2021-11-26 15:11:51 +00:00
d46a6163a0 [PLUGINS][Oomox] Hotfix: cache wasn't set. Proper labels. 2021-11-26 15:01:30 +00:00
180ae15647 [PLUGINS][Oomox] User theme CSS file is served. Settings page needs polish, and option to revert changes. 2021-11-26 14:45:28 +00:00
7fa2418e54 [PLUGINS][Oomox] Theme colours WIP. 2021-11-26 14:45:28 +00:00
6cd7be6abc [UI][CONTROLLER][ENTITY][DOCS] Refactor term 'timeline' into 'feed' 2021-11-26 13:05:23 +00:00
283820a4a5 [UI][ENTITY][Language] Use list rather than hashmap so actor language ordering is preserved 2021-11-26 12:30:21 +00:00
04e6b2fb53 [ENTITY][Language] Properly handle context actor language 2021-11-26 12:29:27 +00:00
d7a71ebe33 [UI][ENTITY][Language] Extend base template for user panel language sorting 2021-11-26 12:28:03 +00:00
6919f38592 [UI][COMPONENT][Tag] Use base template and properly display notes in tag stream 2021-11-26 11:59:11 +00:00
c178054433 [COMPONENT][Tag] Add stream for multiple tags 2021-11-26 11:48:35 +00:00
edf1b30e89 [TOOLS][DOCS] Add missing doc blocks 2021-11-25 23:16:04 +00:00
b1262919da [TOOLS] Fix (most) issues found by PHPStan 2021-11-25 23:08:30 +00:00
8fd02ef152 [TOOLS][COMPONENT][FreeNetwork][PLUGIN][ActivityPub] Temporarily exclude FreeNetwork and ActivityPub from PHPStan analysis, since it's a WIP 2021-11-25 20:37:53 +00:00
98b719dca3 [COMPONENTS][Tag] Split tag into words and stem each 2021-11-25 20:37:53 +00:00
4571b18c60 [DEPENDENCIES] Update dependencies 2021-11-25 20:37:53 +00:00
a64c488e21 [PLUGINS] Add StemWord plugin, which stems words, given a language. Currently used for tags 2021-11-25 20:37:53 +00:00
2d057024b9 [TAGS][ENTITY][Note] Properly store the note language, pass it along when rendering content. Add mechanism for stemming tags, with fallback to simply slug-ifying them 2021-11-25 20:37:53 +00:00
f837df5753 [CACHE] Add way of calculating hash map if key is not found 2021-11-25 20:37:53 +00:00
e64fd5aaf6 [TOOLS] Exclude src/PHPStan from test coverage 2021-11-25 20:37:53 +00:00
c1779dc12d [UI] Don't display short language form in user panel language selection 2021-11-25 20:37:53 +00:00
0194b6b14c [TESTS] Fix tests by adding missing is_local columns and by login in the admin user in the admin panel test 2021-11-25 20:37:52 +00:00
d9544c6edb [CORE][SECURITY] Move to the new authentication format, for Symfony 5.3 2021-11-25 20:37:45 +00:00
05758c999f [ENTITY][Actor] fix typo in findRelativeActors query 2021-11-25 02:07:12 +00:00
d9c0a72e36 [CONFIG] Replaced form theme used since it was too opinionated. 2021-11-24 14:03:50 +00:00
477a5cb92d [CSS] Fixed all buttons/select/input display rules from being overriden. 2021-11-24 12:46:32 +00:00
d8147cbd2d [PLUGINS][AttachmentShowRelated] Fixed note template error. Fixed if statement.
[CORE][Controller] Commented CSP out.
2021-11-24 12:46:32 +00:00
8edaabbabf [TWIG][Settings] WIP Refactoring of user panel. Now using macros to diminish repeated code.
[CONTROLLER][UserPanel] Replaced form names. More readable.
2021-11-24 12:46:31 +00:00
d5fc2cac8a [TOOLS] Make Makefile rule database-force-nuke stop and restart the worker container 2021-11-24 12:46:31 +00:00
30f4131f5d [TESTS] Add missing 'is_local' to actors in data fixtures 2021-11-24 12:46:31 +00:00
206856e1ba [FORM][FormFields] Add way of specifying attributes for password fields (namely form autocomplete=new-password) 2021-11-24 12:46:31 +00:00
3a5e52ee0d [CORE][SECURITY] Move to the new authentication format, for Symfony 5.3
Keep using (deprecated) Guard
2021-11-24 12:46:26 +00:00
b4ce77320e [TESTS] Fix remaining tests, back to 100% passed. Some minor semantic changes 2021-11-20 21:33:25 +00:00
c68d7ae406 [CONTROLLER][UserPanel] Make function names camelCase 2021-11-20 21:33:25 +00:00
7e4a971fac [ENTITY][LocalUser][CACHE] Remove bad keys from getByNickname cache key 2021-11-20 21:33:25 +00:00
0e104a9701 [UTIL][HTML][TESTS] Fix test and implementation and expand HTML generation utilities 2021-11-20 21:33:25 +00:00
fe755f7c42 [UTIL][FormFields] Accomodate use of FormFields::repeated_password without a 'required' option 2021-11-20 21:33:23 +00:00
1dd86a2302 [TESTS] Many tests fixes (already fixed the dependant code) 2021-11-20 21:32:25 +00:00
d254147988 [CSS] Note attachments fixes, fancy note-complementary accents. 2021-11-17 17:28:46 +00:00
0aa43783e8 [PLUGIN][Repeat] Repeat now repeats attachments as it should.
[COMPONENTS][Posting] Now accepts attachments already processed.
[ENTITY][Note] Added getAttachmentsWithTitle().
2021-11-17 17:14:15 +00:00
8077bdb0b5 [CORE][Controller] CSP default-src changed to 'self' to allow internal redirects. 2021-11-17 01:29:36 +00:00
1d31bd651e [CORE][Controller] Added Content-Security-Policy response header. 2021-11-17 00:49:23 +00:00
e1b9ab4b9a [TWIG] Added CSP in base template meta tag. This isn't optimal. 2021-11-16 23:48:12 +00:00
f07dce4604 [UTIL][Form] Fix bug with repeated_password 2021-11-16 23:27:29 +00:00
89d36a68e5 [ENTITY][Actor] Add is_local, it's common to depend, and this makes it much faster, with a low space cost 2021-11-16 23:26:20 +00:00
f1a30ac0e6 [CSS] Added a top margin for buttons. 2021-11-16 19:40:07 +00:00
2561823550 [PLUGIN][Repeat] Fixed corner case where the user would return to repeat form page and try to repeat the note again. 2021-11-16 19:39:03 +00:00
acc43a276b [PLUGIN][Reply] User's own replies wont display their own nickname on rendering the original note. 2021-11-16 19:36:17 +00:00
0dd4b62ded [TOOLS][DOCKER] Add worker container and script, which handles the queues 2021-11-15 19:25:53 +00:00
5e4ada7b78 [DEPENDENCIES] Update symfony to 5.3, which fixes a bug with the doctrine postgres message worker 2021-11-15 19:25:53 +00:00
b8b19abed2 [ENTITY][AttachmentThumbnail] Do not attempt to check if a file exists if the path is null 2021-11-15 19:25:52 +00:00
5cafc80d01 [UTIL][FormFields] Refactor duplicated language choice form entry logic 2021-11-15 19:25:52 +00:00
e6c0db9ee1 [CORE][Cache] Allow retrieving multiple keys from a hashmap 2021-11-15 19:25:52 +00:00
587d701d11 [CONTROLLER][Network] Temporarily remove replies from streams, following planned changes to the Reply plugin 2021-11-15 19:25:52 +00:00
e9cc760ca8 [COMPONENTS][Posting][Right] Fix TypeError (which somehow only popped up in tests) caused by assigning a FormView to an out array param 2021-11-15 19:25:52 +00:00
9dbbc9e18e [PLUGIN][Repeat] Fixed bug where checks dependant on user being logged in were attempted. 2021-11-15 19:25:52 +00:00
6e90e51f0c [PLUGIN][CONTROLLER][Repeat] Fixed Repeat controller to update note_repeat table on removal. 2021-11-15 19:25:52 +00:00
b71e869843 [PLUGIN][Repeat] onAppendCardNote added. getNoteRepeats implemented. 2021-11-15 19:25:52 +00:00
774eb49af4 [UI][CONTROLLER][UserPanel][ENTITY][ActorLanguage][Language][Actor] Add interface to allow user to select thier preferred languages and to order them. Rename ActorLanguage::order to ordering 2021-11-15 19:25:52 +00:00
83fc31b485 [CSS] Polished light theme. 2021-11-15 19:25:51 +00:00
2d941cbb16 [CSS] Fixed Chromium from overriding the page stylesheet on fieldset element. 2021-11-15 19:25:51 +00:00
337fe272a3 [CSS] Re-arranged CSS rules, overall refactor to minimize duplications. 2021-11-15 19:25:51 +00:00
a23f7d5aa3 [CSS] Removed 'colors.css', colors are declared within their respective classes/ids instead. 2021-11-15 19:25:51 +00:00
d5e6fd603d [CONTROLLER][UserPanel] Fix 'could not convert IntergetType to string' error 2021-11-15 19:25:51 +00:00
1abd28c949 [UI][TWIG][CONTROLLER][UserPanell] Add way to expand details with a GET parameter. Implement it in UserPanel 2021-11-15 19:25:51 +00:00
c509692102 [ENTITY][AttachmentThumbnail] Uncache when deleting, cleanup code and ensure the biggest thumbnail is used when the original is not avaliable 2021-11-15 19:25:51 +00:00
a3074662b8 [TESTS] Remove 'reply_to' in note creation in data fixtures 2021-11-15 19:25:51 +00:00
eab6de3609 [TESTS][Security] Fix SecurityTest. Remove nickname normalization on register (a plugin can handle that). Move from filter_var(FILTER_VALIDATE_EMAIL) as it does not support dotless domains 2021-11-15 19:25:50 +00:00
bf5ffe7d3d [CACHE][TEST] Fix errors in cache implementation found by tests 2021-11-15 19:25:44 +00:00
98352cfece [TESTS] Properly provide both createClient and bootKernel in test base class 2021-11-11 12:39:36 +00:00
2239845a00 [CONTROLLER][Security] Remove nickname normalization when trying to login 2021-11-11 12:39:36 +00:00
a1c78696f7 [CORE][Actor][Posting] Fixup Actor::getPreferredLanguageChoices following changes in how the data is cached 2021-11-11 12:39:36 +00:00
316723075b [TESTS] Reload the initial table values after loading the data fixtures (as this purges the DB) 2021-11-11 12:39:36 +00:00
f39f800a8e [TESTS] Add now-required content-type to notes created in data fixtures 2021-11-11 12:39:35 +00:00
f667b558f7 [TESTS] Fix SecurityTest
This test was broken by changes in the routing and in the templates.
However, this revealead a potential open redirect and duplicated code
in the Reply and Favourite plugins
2021-11-11 12:39:28 +00:00
dea9aa4dcf [CORE][Router] Remove duplicate service for URL generation, as that is actually the same object 2021-11-11 12:38:09 +00:00
420ebcda26 [TESTS] Run tests without runuser as it's generating very weird permission errors. This is temporary (TM) 2021-11-11 12:38:09 +00:00
d0f9fde7c2 [PLUGIN][Reply] WIP. Note complementary info now shows who has replied on the original note! 2021-11-10 15:44:28 +00:00
f2f1bdc145 [PLUGIN][Reply] Separated replies from Note table.
[PLUGIN][Repeat] Deleted unnecessary card note template, info now to
appended at the end of note.
[PLUGIN][TreeNotes] WIP to accomodate reply plugin changes.
[TWIG][Runtime] Removed getAdditionalTemplateVars event.
2021-11-10 13:29:53 +00:00
7d8819a3da [DB][CONTROLLER][Network][ENTITY][Note] Fix Note::getAllNotes 2021-11-09 23:38:37 +00:00
c3705112ba [DEPENDENCIES] Update dependencies 2021-11-09 23:38:37 +00:00
98b1b7072c [TOOLS] Fix running tests without filters 2021-11-09 23:38:37 +00:00
f0c532340e [DB] Fix uses of DB::sql, to remove the deprecated second entities parameter 2021-11-08 20:35:38 +00:00
767b2035e7 [ENTITY][ActorLanguage] Remove duplicate specification of 'not null' in table schema 2021-11-08 20:32:10 +00:00
1d84f1629e [CORE][DB] Make DB::sql not error when selecting from tables with columns of the same name and remove the second enitites paramter, calculating it internally instead 2021-11-08 20:32:10 +00:00
f98afd15ce [ENTITY] Refactor Follow as Subscription 2021-11-08 16:14:23 +00:00
68c6dd1ba9 [CORE][Cache] Use hashmaps to store language related items 2021-11-08 16:08:04 +00:00
2eb31952bc [ENTITY][Language] Use varchar as char leads to a padded string, which isn't helpful 2021-11-08 16:08:03 +00:00
2cf3a0b4e6 [COMPONENT][Posting] Display short language signifier rather than the full name for the first preffered language 2021-11-08 16:08:03 +00:00
705bf815ab [CACHE] Add partial implmentation for caching hashmaps (non-list arrays, i.e. array<string,string>). No non-redis-fallback yet 2021-11-08 16:08:03 +00:00
cd470cbf93 [CORE] Fix loading of settings from modules 2021-11-08 16:08:03 +00:00
019ad794d1 [Posting] Add dropdown with language choice, with preferred choice according to user choice and context (group, etc) 2021-11-08 16:08:02 +00:00
9444c34071 [ENTITY][Actor][ActorLanguage][Language] Remove Actor::preferred_lang_id. Add ActorLanguage::order. Add Language::{short_display,long_display}. Instead of an actor having a single preffered language, the entries in ActorLanguage should be used, sorted by ActorLanguage::order 2021-11-08 16:08:02 +00:00
2bd05fbd47 [TOOLS][COMMAND] Add 'app:populate_initial_values' command, which inserts values into the language table if it does not yet contain values. Add database-force-nuke to Makefile, which does all the steps necessary to reset the database 2021-11-08 16:08:02 +00:00
1960f6944f [CORE][DB] Fix error in regex that prevented selecting collumns that are named the same way a column is 2021-11-02 11:14:59 +00:00
839fa070c7 [CORE][Posting] Default Posting language to site language, if the user hasn't selected one 2021-11-02 11:14:59 +00:00
d9265c5402 [TEMPLATES][Profile] Use URI instead of URL 2021-11-02 08:34:44 +00:00
c4088e221f [CSS] Very important colour change. 2021-11-01 22:09:10 +00:00
cf09b48e92 [PLUGINS][Repeat] Added note_repeat entity, fixed visual discrepancies, and completed the expected functionality.
[ENTITY][Note] Removed repeat_off from table. It is now part of the Repeat plugin.
2021-11-01 21:19:56 +00:00
73e772e576 [TOOLS] Allow specifying a list of filters when running tests with make. When running make test foobar only the test foobar is executed (read the documentation for phpunit --filter) 2021-11-01 12:16:50 +00:00
c862c9bf18 [ActivityPub] Make remote mentions great again 2021-11-01 12:16:46 +00:00
712d1739e4 [UTIL][Formatting] Make local mentions great again 2021-11-01 12:16:29 +00:00
91dd6e1428 [Controller][Security] Fullname is not setup automatically upon registering anymore.
[ENTITY][Actor] Changes to accomodate fullname from potentially being null.
[ENTITY][Note] Changes to accomodate fullname from potentially being null.
2021-10-29 22:05:10 +01:00
ac8513741d [CSS] New themes! No images used anymore. 2021-10-29 22:01:28 +01:00
eb5bc36390 [CSS] Fixed widgets from overflowing. 2021-10-29 18:14:39 +01:00
7fef18e95a [COMPONENTS][Posting] LocaleType::class doesn't have a default attribute, replaced with 'preferred_choices' instead. 2021-10-29 17:46:25 +01:00
9a23e03330 [PLUGINS][Repeat] Repeat template override WIP. 2021-10-29 17:26:20 +01:00
0f358a9c5d [CORE][Posting] Add language choice field to the note posting block 2021-10-28 17:37:00 +01:00
44454ac28a [UTIL][TemporaryFile] Ensure resource is neither false nor null when attempting to cleanup, otherwise getRealPath returns false and we get sad 2021-10-28 17:36:02 +01:00
458c09485a [CORE][ENTITY] Move preferred language setting from [LocalUser] to [Actor], make [Language] language unique and make [Note] content_type not null 2021-10-28 17:34:01 +01:00
e6c5312025 [CORE][GSFile] Add check_is_supported_mimetype option to GSFile::storeFileAsAttachment 2021-10-28 17:29:57 +01:00
4d9a5aae5a [ActivityPub] Always explicitly compare the results of Event::handle to the constants next or stop 2021-10-28 17:28:02 +01:00
86ac5c52a1 [TESTS] Add to the supported configuration list, the mimetypes of all sample-upload files 2021-10-28 17:26:57 +01:00
8238980395 [TOOLS] Allow specifying a list of filters when running tests with make. When running make test foobar only the test foobar is executed (read the documentation for phpunit --filter) 2021-10-28 17:24:43 +01:00
a55d60d880 [DEPENDENCIES] Update dependencies 2021-10-28 14:31:56 +01:00
c352e40518 [CORE][Controller] Allow plugins to override the Twig templates 2021-10-28 14:29:34 +01:00
18aeeb3850 [ENTITY] Add a [Language] table, which has a char 64 field that maps to an int. This is then used in [Note], [LocalUser] and [ActorLanguage] 2021-10-28 11:26:34 +01:00
3388e0e8f1 [TWIG][Cards] Note template fully refactored. Template has now macros for different views for the card.
[PLUGINS][Repeat] WIP: Action added.
[PLUGINS][Favourite] Changes to accomodate note card template refactoring.
[CSS] Fixed textarea from being resized horizontally.
2021-10-27 20:44:51 +01:00
d47f125894 [PLUGINS][Favourite] Refactored redirection to previous url. User is now unable to do invalid actions (ex. favour an already favourited note).
[PLUGINS][ActivityPub] Fixed favour route id to be more consistent.
2021-10-27 20:44:50 +01:00
e54e55dfbf [EXCEPTION][RedirectException] You are now able to redirect to a specific url. 2021-10-27 20:44:50 +01:00
3e2fefa8af [TWIG][Cards] Fullname is now displayed as the note author, nickname as an identification.
[CONTROLLER][Security] Fullname is set on resgistration to enable it to be shown by default in notes.
[CONTROLLER][UserPanel] Fullname extra step added.
[CSS] Fullname and nickname representation work.
2021-10-27 20:44:50 +01:00
51c984849f [ActivityPub] Port Explorer 2021-10-27 04:22:19 +01:00
5189269e5b [FreeNetwork] Port Discovery 2021-10-27 04:22:18 +01:00
3cdaf6671a [CORE][HTTPClient] Add some shortcut functions inspired by pre-v3 2021-10-27 04:22:18 +01:00
3227e1f919 [CORE][Log] Document magic methods 2021-10-27 04:22:18 +01:00
45f65baf96 [PLUGINS][Embed] Polished embed template in order to better utilize space.
[CSS][Feed] Embed related additions.
2021-10-27 04:19:34 +01:00
0407ac38cf [AudioEncoder] Introduce basic audio plugin to provide an attachment template and duration metadata for audio mimetype 2021-10-27 04:19:34 +01:00
364c14ef2c [COMPONENT][Link] Fix mistake where only the first URL was matched and the match included the preceeding whitespace character 2021-10-27 04:19:34 +01:00
ebf675ec59 [Plugins][FAVOURITE] Redirect added. Only redirects from the route the user came from, not the anchored note. To be added. Further corner cases fixed. 2021-10-27 04:19:33 +01:00
56ba7bd845 [ImageEncoder][VideoEncoder] Properly decide when to take action 2021-10-27 04:19:33 +01:00
bccafd0d7b [CORE][GSFile] Respect mimetype whitelist and extensions blacklist before saving files 2021-10-27 04:19:33 +01:00
b7d9da8ae6 [Posting] Add Content Length constraint to form validation 2021-10-27 04:19:33 +01:00
8038fdbce9 [UTIL][Common] Added Common::getUploadLimit().
[COMPONENT][Posting] Update Posting to warn the user of submtting attachments too large.
2021-10-27 04:19:32 +01:00
656c2c7812 [SECURITY][Authenticator] fix wrong route id on after login redirection 2021-10-27 04:19:32 +01:00
60b15ea79d [Plugins][FAVOURITE] No longer a form, a link to a new page is provided instead. The amount of forms per page were blocking rendering for the majority of its duration. 2021-10-27 04:19:32 +01:00
a6d5752748 [TOOLS][PHPStan] Make a standalone phpstan executable, which executes inside the docker container 2021-10-27 04:19:31 +01:00
299e893ca9 [TOOLS][PHPStan][DocCheck] Fix errors found by PHPStan and Doc Check 2021-10-27 04:19:31 +01:00
769b901060 [TOOLS] Add doc-check target to Makefile 2021-10-27 04:19:31 +01:00
dff5647b97 [DB][Note] Add langauge field to notes 2021-10-27 04:19:31 +01:00
8a10fec31d [CONTROLLER][UserPanel] Make all fields in settings not required 2021-10-27 04:19:30 +01:00
2694d83ae4 [TOOLS][CS-FIXER] Run new PHP CS Fixer config. Notably, adds strict_types 2021-10-27 04:19:30 +01:00
028ea79fff [CORE][Router] Properly act on Accept headers 2021-10-27 04:19:30 +01:00
eli
99fd2f725b [Core][Util] Hotfix: In App\Core\DB\DB persistWithSameId, casting the id to an int. In App\Util\HTML html, tag is now evaluated beforehand, making sure it's a string. 2021-10-27 04:19:30 +01:00
eli
f78cfed41a [TWIG][CSS] Template refactoring, classes and their respective CSS is now more consistent. CSS variables are back. 2021-10-27 04:19:29 +01:00
8fdc52636f [ActivityPub] Port RSA 2021-10-27 04:19:29 +01:00
8544fe157b [FreeNetwork] First steps porting webfinger/lrdd to v3, GET webfinger requests already have a basic result 2021-10-27 04:19:29 +01:00
44cf1fa24c [UTIL][Nickname] Fix some parameters issues found with strict types 2021-10-27 04:19:29 +01:00
5eefea7a29 [TOOLS] Update Makefile to support both the new and old container naming conventions, as of docker-compose v2 2021-10-27 04:19:28 +01:00
b524c5bc90 [TOOLS][PHPStan] Add missing toString on the call to DB::filterName, as it seems something changed in some update 2021-10-27 04:19:28 +01:00
b65ee4c21d [TOOLS][CS-FIXER] Fix incorrect transformation 2021-10-27 04:19:28 +01:00
9109c61af5 [TOOLS][CS-FIXER] Run new PHP CS Fixer config. Notably, adds strict_types 2021-10-27 04:19:28 +01:00
8ef2d3339f [COMPONENTS][Search] Slightly refactor parser, since the inline lambda was somewhat complex (and cs-fixer kept moving the comment, so doc-checker complained) 2021-10-27 04:19:27 +01:00
703e66fd2e [TOOLS] Update PHP CS fixer and adjust configuration 2021-10-27 04:19:27 +01:00
7aad58b440 [DEPENDENCIES] Update composer dependencies 2021-10-27 04:19:27 +01:00
ce0cfa7a63 [COMPONENT][Search] Update Search to be able to search for either notes or actors 2021-10-27 04:19:27 +01:00
d575f8aef5 [UTIL][Formatting] Make it possible to supply string|array to either or both argument of Formatting::{starts,ends}With 2021-10-27 04:19:26 +01:00
99ab24ec23 [CORE][Controller] Allow routes without text/html response
Improve GET getters
2021-10-27 04:19:23 +01:00
03f6029ce5 [SECURITY] Fix nickname validation and properly allow email auth 2021-10-18 13:22:55 +01:00
071b769997 [CORE][Util][Common] Correct behaviour for absense of value 2021-10-18 13:22:45 +01:00
517ed953f2 [FreeNetwork] First step towards de-duplication mechanism for federation
Refactored AS2 inside AP; [ENTITY][Activity] went from core to AP
Webfinger plugin will be part of FreeNetwork component
2021-10-06 11:48:22 +01:00
eli
bd5c426046 [TWIG] Removing unnecessary CSS classes. Removing network/feed CSS preloading. 2021-10-06 00:45:37 +01:00
eli
3cb6563c40 [TWIG][EndShowStyles] Route as an event argument 2021-10-06 00:34:27 +01:00
eli
6412b632ab [CSS] Note actions size further compatibility work. 2021-10-05 23:36:15 +01:00
eli
e467cf5ec2 [CSS] Fixed: note actions size. 2021-10-05 23:29:46 +01:00
eli
31857e1eab [CSS] Fixed: User panel hr elements styling. 2021-10-05 23:00:16 +01:00
eli
1d6b22551b [CSS] Fixed: Body text colors weren´t applied. 2021-10-05 22:51:46 +01:00
eli
d4513e3597 [CSS] Browser compatibility improvements. 2021-10-05 22:44:22 +01:00
eli
78dd7137f8 [PLUGIN] ProfileColor color settings can be null. 2021-10-05 19:12:51 +01:00
eli
a268aee53a [CSS][PLUGIN] ProfileColor now handles both the background and foreground colors. Various button CSS fixes. 2021-10-05 19:04:30 +01:00
eli
5373655170 [CSS] Firefox ESR doesnt know what a colour is. 2021-10-05 16:09:01 +01:00
eli
2a2331d692 [CSS] Colours by classes. Refactored all CSS. 2021-10-05 16:03:17 +01:00
eli
caa04525bd [CSS] Fixed embed width. 2021-10-04 17:16:53 +01:00
eli
1705b543d3 [PLUGIN] Delete note action added. If the author of a note is logged in, the action will be added to that note. Once the author presses it, the note will be deleted from the DB. 2021-10-04 17:11:44 +01:00
eli
70d1521a2b [CSS] Fix: article header was being selected has the page header. 2021-10-04 15:30:01 +01:00
eli
17a13b3f20 [CSS] Fix: Left and right panel checkbox border when active. 2021-10-04 12:31:06 +01:00
eli
0dfb41230e [CSS] Fix: Instance name centered. 2021-10-04 12:20:31 +01:00
eli
80d1be323d [COMPONENTS][Search][CSS] Extra header forms now accessible through a details element. Re-organizing templates structure. 2021-10-04 12:17:14 +01:00
eli
d38ad60c76 [COMPONENTS][CSS] Adding components styling properly. 2021-10-01 17:25:51 +01:00
eli
441c411efe [CSS] Complete re-organization of stylesheets. 2021-10-01 16:37:28 +01:00
19c2a91232 [TOOLS][PHPStan][ProfileColor][ENTITY][TEST][AttachmentThumbnail] Fix issues reported by phpstan 2021-09-27 19:50:56 +01:00
de984ac8e1 [COMPONENTS][Search][Tag] Implement basic search functionality that allows only searching through note tags, currently 2021-09-27 19:50:56 +01:00
1107d8257d [TWIG] Add instanceof test
Use with:
{% if var is instanceof(Namespace\Class) %}
2021-09-27 19:50:56 +01:00
2d8b220e92 [CORE][Controller] Make Controller abstract, handle an optional non static method and use static::class rather than get_called_class 2021-09-27 19:50:56 +01:00
4fef97f930 [CSS] Profile text mix blend difference with background. Browser's cache
was playing tricks on me and wouldn't display the changes accordingly.
2021-09-27 19:40:34 +01:00
ab26162217 [CARDS][Profile] No longer ids, now classes (CSS). Profile info nickname for instance. The inversion filter now actually works. 2021-09-25 22:30:46 +01:00
f8c108bdf3 [CSS] Profile text color doesn't blend in anymore. 2021-09-25 21:42:23 +01:00
fdd43f4b11 [CSS] More consistent padding across input elements. 2021-09-25 21:12:07 +01:00
5249ccfc68 [Posting][CSS] Right panel form render simplified. 2021-09-25 21:02:11 +01:00
3001f91918 [CSS] Very slight shadow on key elements. 2021-09-25 20:36:07 +01:00
ff26831d1e [CSS] Note action icons back to a sane size. 2021-09-25 19:59:06 +01:00
20ae2dba5d [CSS] Reverting desktop side margins. All margins, sizes, radius, etc were redone. 2021-09-25 19:40:18 +01:00
4a17adc182 [PLUGINS][ProfileColor] Actors are now shown with their own colors for other. 2021-09-25 19:40:17 +01:00
7b8eb3fda9 [PLUGINS][ProfileColor] Current color is now selected by default. Not found exception is now handled. 2021-09-25 19:40:17 +01:00
a681acae67 [ENTITY][AttachmentThumbnail] Every image should have width and height attributes 2021-09-25 19:40:11 +01:00
808da203ad [PLUGINS][ProfileColor] Settings page render problem fixed. ColorType given data wasn't a string. 2021-09-25 12:51:25 +01:00
57b94af9f6 [PLUGINS][ProfileColor] Re-organized plugins templates and assets. ProfileColor plugin fixed. 2021-09-25 11:17:56 +01:00
765cf66ff2 [CSS] Simplified window resize media queries. Desktop view's left and right margins were wrong. Some embedded links with empty blocks had padding on them again, fixed. 2021-09-25 09:02:13 +01:00
321d5b4be8 [CSS] Embedded width didn't conform to note's own properly. 2021-09-23 17:22:44 +01:00
fe77dc0996 [CSS] Resetting headers browser styling. Fixing embedded links styling inconsistencies. 2021-09-23 17:15:11 +01:00
3268559f9a [AttachmentThumbnail] Use other thumbnail when requested isn't available and there's no original file 2021-09-23 16:19:50 +01:00
b6d80003d8 [CSS] Note attachments layout fix. Added a very small radius to avatars. 2021-09-23 16:18:23 +01:00
3ef1077f90 [DOCKER] TODOify mail server certificate 2021-09-23 15:47:51 +01:00
be8610a7a1 [CSS] Note attachments uses a grid layout now. 2021-09-23 15:39:14 +01:00
af3531f1c7 [CORE][GSFile] Add type annotation to the $encoders used in attachment handling 2021-09-23 14:54:21 +01:00
bb81f1f717 [Embed] Use new attachment route format 2021-09-23 14:54:21 +01:00
6a2c3eb711 [ImageEncoder] Ensure proper memory limits are used when loading images from disk 2021-09-23 14:54:21 +01:00
1c1bef76ef [Cards][Navigation] Navigation cards! Left panel now composed entirely of cards. 2021-09-23 14:46:18 +01:00
21e598d877 [ENTITY][Actor] Fix issue with deleting a self tag 2021-09-23 14:34:34 +01:00
4820a863a9 [Avatar] Fix cache usage and other minor bugs 2021-09-23 14:34:34 +01:00
64c881173b [Cards][Profile] Fixing nested anchor tags. 2021-09-23 13:53:02 +01:00
a439b7130e [Cards][Profile] Re-organizing elements. 2021-09-22 17:20:06 +01:00
a557ba0224 [Timelines][Plugins][Left] Plugins now provide their path ID. Feed redone as it's own independant template. 2021-09-22 16:47:06 +01:00
05f16a3084 [ENTITY][AttachmentThumbnail] Now thumbnails are always only available in three sizes: small, medium, big
Commit jointly produced with eli (Eliseu Amaro)

Breaking change: Entity changed to only store the tinyint referring to the size stored

With this, the logic was simplified and now it's not possible to make an
instance produce unnecessary thumbs. The aspect ratio is preserved and
thus the thumbs will always look nice. New configuration was added to
maintain flexibility.
2021-09-22 15:13:46 +01:00
7beb5c2995 [GSFile] Fix sanitize configuration 2021-09-22 15:13:46 +01:00
c1e7d486a3 [Posting] Fix bug with early DB::flush that would discard attachments relations 2021-09-22 15:13:44 +01:00
3f618c2674 [TWIG][Cards][Profile] Card templates! Profile now has a card template to be used everywhere you need to show quick actor information. 2021-09-22 14:11:59 +01:00
c6082bab10 [COMPONENT][Tag] Update tag stream to use new pagedStream format 2021-09-21 16:39:36 +01:00
69e7dc44bd [ENTITY][Note] Change isVisibleTo to allow for not supplying an actor 2021-09-21 16:38:50 +01:00
879f54c772 [CACHE] Filter notes by scope in pagedStream
This currently does not return a fixed number of notes per page. Fixing this is left as an exercise to the reader
2021-09-21 16:37:51 +01:00
14c173df7a [CACHE][COMPONENT][Tag] Add generic Cache::pagedStream and use it for the tag stream. Note that it doesn't respect scope yet 2021-09-21 15:35:07 +01:00
6cd86cac25 [COMPONENT][Tag] Add tag stream, with paging 2021-09-21 11:04:27 +01:00
2f3f7b8469 [COMPONENTS][Posting][Link][Tag] Pass the note, not just the id in ProcessNoteContent 2021-09-21 11:04:27 +01:00
7926f18f93 [CONFIG] Add streams:notes_per_page config value 2021-09-21 11:04:27 +01:00
6715a036e9 [CACHE] Add way to fetch limit,offset values from a list 2021-09-21 11:04:26 +01:00
15a87055a6 [DOCKER][Redis] Add way to override Redis config. Default to only one database 2021-09-21 11:04:26 +01:00
ce80065775 [DB] Add mechanism for specifying limit and offset in dql query 2021-09-21 11:04:26 +01:00
91fd7d1cfa [CONFIG][CORE] Fix bug in overriding default config 2021-09-21 11:04:14 +01:00
8bb6285522 [ENTITY][Note] A note may have no content 2021-09-20 17:06:21 +01:00
b7298eaa44 [ENTITY] ActorTag: use getter for tag name on toString 2021-09-20 17:05:50 +01:00
9e4c43e8fd [ActivityStreamsTwo] Further work on routes and use render event on note's content 2021-09-20 17:05:04 +01:00
7813723ca1 [ActivityPub] Inbox must work without actor, specify source for AS2 2021-09-20 17:03:23 +01:00
958cbffb91 [Posting] Add text/html content type, must actually treat it 2021-09-20 17:02:35 +01:00
85969a8cff [Avatar] Add default avatar route and improve url getter 2021-09-20 17:01:36 +01:00
0ef151edac [CSS] Now properly following Van de Graaf / Tschichold Page Construction Canon. 2021-09-20 16:06:57 +01:00
543853c374 [PLUGINS][Actor][Profile] Current user profile in line with other users. Directory plugin actor template standardized. 2021-09-20 14:39:11 +01:00
8fe8687c5b [UTIL][HTML] Move to a unified array 2021-09-20 13:28:18 +01:00
e8f4563633 [UTIL][Formatting][COMPONENT][Link][Tag] Refactor code from formatting into Link and Tag, where appropriate. Drop 'perfect url regex' as the one used in v2 is better 2021-09-20 13:28:18 +01:00
556b8f8265 [ENTITY][NoteTag] Add 'canonical' field to tag 2021-09-20 13:27:27 +01:00
04174bc56d [UTIL][UI] Change how plaintext notes are rendered to be split into paragraphs. Remove span around tags 2021-09-20 13:27:27 +01:00
51c7e10483 [UTIL][HTML] Allow specifying options: [raw => bool], whether to escape the provided inner HTML or not. Use with care 2021-09-20 13:27:21 +01:00
baeb1dde7a [Posting][CSS] Fix for qtwebengine and gecko not displaying background color on input elements.
Minor bug fixes.
2021-09-20 12:49:05 +01:00
67d62cf37b [TWIG] Remove kludge event TwigPopulateVars 2021-09-18 07:27:35 +01:00
fda998e335 [Avatar] We definitely don't need an event to retrieve avatar urls 2021-09-18 07:26:10 +01:00
2bd19fa087 [NOTE][Posting] Revert regressions introduced with c90efe2c52
Entity Note: It doesn't make sense to handle attachments on Note::create.
Attachments exist out of Notes, they are a thing on their own.
Furthermore, they aren't always handled the same, they most definitely
aren't always uploaded files.

FileQuota: It doesn't make sense to check if a file is greater than max
allowed upload size here. The plugin ensures a user is inside his
allowed quota, it's ignorant to anything else. Whether a file respect
max upload is a core thing that must be handled directly in the Posting
component. TODO: The configuration regarding user and monthly quota
must become FileQuotaPlugin settings and be removed from core.

c90efe2c52 - [UI] Add mechanism for rendering note contents in different formats. Implement plaintext rendering. Use rendered field for note content, rather than the content itself
2021-09-18 05:12:18 +01:00
941cbe6599 [Actor] Refactor GSActor into Actor 2021-09-18 05:12:17 +01:00
6c899b7b61 [Plugins][Components] Fixed issue where right panel form was rendered multiple times in actors plugin page. Actors page done. 2021-09-18 05:12:16 +01:00
e4b650be46 [PLUGINS][Settings] Removed unused templates. Directory plugin templates now using actual templates. Notification settings using details element now. 2021-09-18 05:12:16 +01:00
d6f31d102a [CORE][ActivityStreamsTwo][ActivityPub] Set all routes
Allow global routes to act for every actor
Fix Favoured stream query
2021-09-18 05:12:15 +01:00
738168461c [CSS] Note avatar hotfix. 2021-09-18 05:12:14 +01:00
447372d7f6 [CSS] Note actions re-alignment to previous position. Simplified visuals. 2021-09-18 05:12:13 +01:00
f4ac49e7c7 [CSS] Note avatar now bigger. Note actions and avatar now on the side of note. 2021-09-18 05:12:13 +01:00
2de071ca7e [CSS] Note attachments rules simplified. Proper resizing on smaller views. 2021-09-18 05:12:12 +01:00
a4a7039786 [CSS] Less redraws on details element hover feedback. 2021-09-18 05:12:11 +01:00
380eec5eb0 [CSS] Fixed inconsistent side panels font size. Note's view improvements. 2021-09-18 05:12:11 +01:00
b8e66aa9bf [CSS] Scrollable panels. Attachments width is retained on view now. 2021-09-18 05:12:10 +01:00
42f9a6a79c [CSS][Attachments] Attachments page view done. Standardized left and right panels sections. Applying styling through key classes to be defined in docs. 2021-09-18 05:12:10 +01:00
eda3a5ffb6 [DOCUMENTATION][DB] Fix database examples and documentation 2021-09-18 05:12:09 +01:00
ee7721da96 [DOCUMENTATION] Add documentation on developer tools 2021-09-18 05:12:09 +01:00
b177cb69e7 [HTML][SECURITY] Harden implmentation of HTML generation 2021-09-18 05:12:08 +01:00
030f8afdf5 [ASSETS][FONTS] Poppins and Opens Sans are now used. Better legibility for smaller sizes. 2021-09-18 05:12:07 +01:00
c0c7eb32dc [DEPENDENCIES] Update composer dependencies 2021-09-18 05:12:07 +01:00
8f0a3e4977 [UI] Add mechanism for rendering note contents in different formats. Implement plaintext rendering. Use rendered field for note content, rather than the content itself 2021-09-18 05:12:06 +01:00
f344ed376c [ATTACHMENTS][Embed][UI] Allow plugins to provide a title for an attachment, if a note has none, implement such a mechanism in Embed and cache the result, since it is potentially costly 2021-09-18 05:12:06 +01:00
15a2a69274 [ROUTER] Add option is_system_path, to allow specifying that a route, such as gsactor_view_nickname should not be considered a system path, when checking for the collision of nicknames 2021-09-18 05:12:05 +01:00
e563c393f8 [ROUTER] Add mechanism for sorting the order in which core routes are loaded 2021-09-18 05:12:05 +01:00
b26f3bca14 [BOOTSTRAP] Remove duplicate constant definition 2021-09-18 05:12:04 +01:00
e9d809d441 [Security][Exception] Security exception handling, login and register. TODO EmailNotFoundException and NicknameNotFoundException. 2021-09-15 14:48:06 +01:00
26af284353 [CONTROLLER][SECURITY] Registration feedback. The flashError works. However, Symfony's Exception error page is viewed upon trying to register. 2021-09-15 14:48:06 +01:00
efafc9f7eb [TWIG][NOTE] Note's author avatar size defined. 2021-09-15 14:48:06 +01:00
2cbdd43660 [TWIG][BASE] Using preload for main stylesheets. This ensures they are available earlier and are less likely to block the page's render, improving performance. 2021-09-15 14:48:06 +01:00
0f1bce67a1 [CSS][FONTS] Added a lighter font, mobile optimizations were needed. All icons are more consistent in size. Forms are more consistent in margins, paddings and grouping. 2021-09-15 14:48:06 +01:00
365edbaff0 [ActivityStreamsTwo] Initial Actor support
Various bug fixes
2021-09-15 10:26:53 +01:00
1f3a6fe6ac [TESTS] Fix and/or temporarily disable failing tests. We'll get back to this 2021-09-14 13:36:30 +01:00
bebf4fdbce [I18n][Posting] Move ':' to inside the translate call 2021-09-14 13:13:45 +01:00
1adde913c6 [PHPStan] Only run custom PHPStan extensions if environment vairable PHPSTAN_BOOT_KERNEL is defined (since it requires having the whole social setup available) 2021-09-14 13:13:45 +01:00
a21b0afb70 [ASSETS] Removed unused fonts. Variable fonts now used. 2021-09-14 13:13:45 +01:00
7c465bba5f [NOTE] Add mimetype to notes 2021-09-14 13:13:45 +01:00
c69b28d894 [CORE] Fix Undefined array key 0 in DB::filterTableName 2021-09-14 13:13:45 +01:00
404442ebda [BASE] Importing fonts through CSS instead, minimizing content blocking. Removed legibility optimizations in font rendering. Removed unused font rules. 2021-09-14 13:13:45 +01:00
8887efe305 [THEME][DARK] Background image is 73% smaller, added noise to diminish the banding in Firefox. 2021-09-14 13:13:45 +01:00
b74d944ae3 [TOOLS][PHPStan] Raise PHPStan level to 3 and fix new errors 2021-09-14 13:13:45 +01:00
9d7f43cd28 [TOOLS][PHPStan][TESTS][Docker] Rework testing Docker container into a more generic tooling container. Keep services up and run coverage and phpstan as commands, for performance and ease of use 2021-09-14 13:13:44 +01:00
9742a07bae [TOOLS][git] Add option to skip pre-commit steps by defining one of SKIP_ALL, SKIP_CS_FIX, SKIP_DOC_CHECK, SKIP_PHPSTAN variables before the git commit command
Example:
`SKIP_PHPSTAN=1 git commit`
2021-09-14 13:13:44 +01:00
f81bf4a257 [TOOLS][PHPStan] Add mechanism for initializing the whole application 2021-09-14 13:13:44 +01:00
ddb9702b1c [TOOLS][PHPStan] Add support for deducing the correct entity type from a table name. Needs refactoring and can only run inside container, as it connects to the database itself 2021-09-14 13:13:44 +01:00
4e30e5aad9 [TOOLS] Fix all issues found by PHPStan level 2 2021-09-14 13:13:44 +01:00
4b1780a2ee [ActivityStreamsTwo] Introduce a structure for data representation in ActivityStreams 2.0
Type factory borrowed from landrok/activitypub
2021-09-14 13:13:44 +01:00
043c5da58b [THEME][BASE] New and better light theme. 2021-09-14 13:13:44 +01:00
26aec5f626 [BASE][NOTE][CSS] Further screen reader cues for note replies. 2021-09-14 13:13:44 +01:00
9e051273f7 [BASE][NOTE][CSS] Notes are now clearly delimited to visually impaired users. Screen readers will notify when a note begins as well as each reply. Focused elements now provide the same feedback everywhere. 2021-09-14 13:13:43 +01:00
60af533fa4 [BASE][CSS] Accessibility menu fix when logged out. Proper selector for accesskey used now, ".accessibility-target". 2021-09-14 13:13:43 +01:00
c4b328c03b [LEFT][CSS] Fix scrolling when tabbing, navigating through notes is more obvious now. Timeline navigation fix for screen readers to know that the navigation title matters. 2021-09-14 13:13:43 +01:00
3abf71b707 [CSS] There's no need to tab again after selecting accessibility menu! 2021-09-14 13:13:43 +01:00
8123086881 [Embed] Fix normalizeEmbedLibMetadata for thumbnails starting with '/' 2021-09-14 13:13:43 +01:00
3c1a9ba3fa [CSS] Fixed tabbing through accessibility menu. Was invisible when going throught it without a previous target. 2021-09-14 13:13:43 +01:00
b0b3ae237a [TWIG][BASE] Fixed taborder, Orca will continue to read the whole header though. Navigation should be more clear for each timeline. 2021-09-14 13:13:43 +01:00
61071a6821 [PLUGINS][Reply][Repeat][Favourite] Base template semantic rework. Reply, repeat and favourite respective classes are now assigned in their NoteHandlerPlugin. 2021-09-14 13:13:43 +01:00
ddd2ffe26a [TWIG] Add extension to check if Firefox is being used 2021-09-14 13:13:43 +01:00
0e50f0692e [ACCESSIBILITY][BASE] Accessibility menu was unreachable. 2021-09-14 13:13:42 +01:00
1614b8c8fe [ACCESSIBILITY][BASE] Workaround Firefox amazing keybindings. 2021-09-14 13:13:42 +01:00
681144b380 [PLUGINS][Favourite][CSS] Favourite label now shows whether it's favourited or not already. 2021-09-14 13:13:42 +01:00
0cecc67376 [COMPONENT][Posting][Link] Create ProcessNoteContent event. Move link extraction to Link component. Cleanup Posting 2021-09-14 13:13:42 +01:00
add8f4a52f [TOOLS] Fix all errors found by PHPStan level 1 2021-09-14 13:13:42 +01:00
0da6ff05ed [TOOLS] Add config file and raise PHPStan to level 1 2021-09-14 13:13:42 +01:00
277a080d7c [EXCEPTION] Add NotImplementedException 2021-09-14 13:13:42 +01:00
eb833b62e2 [TOOLS] Fix all level 0 errors found by PHPStan and move constant definition to bootstrap file 2021-09-14 13:13:42 +01:00
0eb0236feb [TOOLS] Run PHPStan on the whole codebase on each commit 2021-09-14 13:13:42 +01:00
ecb1064d08 [DEPENDENCIES] Add PHPStan as a dev dependency 2021-09-14 13:13:42 +01:00
6ac37bc7fb [DEPENDENCIES] Update dependencies 2021-09-14 13:13:41 +01:00
f65e2b90f2 [CORE] Fix use of Exception class without import 2021-09-14 13:13:41 +01:00
cbbef90752 [UTIL][CONFIG] Ensure setConfig uses a locals key 2021-09-14 13:13:41 +01:00
4916c8cbda [CONTROLLER][AdminPanel] Add missing Exception import 2021-09-14 13:13:41 +01:00
bfd0acacd1 [TESTS] Fix SecurityTest breakage following UI changes 2021-09-14 13:13:41 +01:00
e8ae0b74e0 [CORE][Controller] Switch order for content negotiation: allow events to take precedence. Bring back default JSON response 2021-09-14 13:13:41 +01:00
bc5ddc52ea [UI] Remove stray template file foo.html.twig 2021-09-14 13:13:41 +01:00
c612fe6df5 [PLUGINS][Reply][CSS] Help text added. Styling reply page done. 2021-09-14 13:13:41 +01:00
9f6acc04aa [CSS] Light theme panels background image fix. Input elements with proper padding. 2021-09-14 13:13:41 +01:00
7a0e256557 [CSS] Light theme! 2021-09-14 13:13:40 +01:00
727133b6ed [IMAGES][CSS] Dropdown image added for use in select boxes background. Fixed select box background color from being the one used by the system, dark theme inconsistencies found. 2021-09-14 13:13:40 +01:00
e6449bfe96 [CONFIG][TWIG] Selected a new default form theme. Forms shouldn't have class-less divs now. 2021-09-14 13:13:40 +01:00
1f792a0183 [CSS] Links should be aligned with content now. Underlined in main content by default. Highlighted when focused. 2021-09-14 13:13:40 +01:00
bdde047dfa [PLUGINS][Embed] Embed references a table that does not exist. It seems to mean attachment_embed, rather than link_to_attachment 2021-09-14 13:13:40 +01:00
cd89106fc0 [EXCEPTION][RedirectException] Add prevention for open redirects by default and ensure we can redirect to the same page 2021-09-14 13:13:40 +01:00
16cde6dfd7 [PLUGINS][Reply] Redirect back to previous URL on note reply. Move controller to own class
This should be safe against open redirects, as it doesn't allow redirecting to other domains
2021-09-14 13:13:40 +01:00
0a7fd9c460 [CORE][MODULES][NoteHandlerPlugin] Add missing import for Event 2021-09-14 13:13:40 +01:00
1d5fd1aefa [CORE][Controller] Fix Controller::__invoke so it actually passes on the route parameters to the controller method. Add Controller->string, which gets a query parameter as a string value, or null if not set 2021-09-14 13:13:40 +01:00
330143e549 [ROUTER][DOCUMENTATION] Add Router::isAbsolute, add documentation to Router::url and `s/setRouter/serServices/ 2021-09-14 13:13:39 +01:00
61d95265a9 [PLUGINS][Repeat] Delete note repeat rather than the original Note. Don't fetch when we want a simple count 2021-09-14 13:13:39 +01:00
be27a10244 [EVENTS] Rename event RouteInFormat to ControllerResponseInFormat 2021-09-14 13:13:39 +01:00
f371443884 [CSS] Note's view now properly handles replies. 2021-09-14 13:13:39 +01:00
6fdec483cd [Reply] RedirectionException wasn't allowing other handlers to do their job. 2021-09-14 13:13:39 +01:00
85db9464ca [Reply] Fixed reply plugin action, there was no need to query the database when handling. 2021-09-14 13:13:39 +01:00
f000532b7e [Favourite][Reply][Repeat] The respective svg for note actions is assigned. Repeat note handler needs work. "An exception has been thrown during the rendering of a template ("No value in table note matches the requested criteria")." exception thrown on repeat. 2021-09-14 13:13:39 +01:00
f9f4f179bb [Security][Right] login
and register padding fix. Select boxes styling done.
2021-09-14 13:13:39 +01:00
983e0303a5 [ROUTER] Sort routes so that the one with a smaller list of Accept types matches first
This requires a copy, but gets cached, so it's the ideal place to do it.

Note that only routes that match the incoming Accept match anyway, so the order between those with different accept types is not relevant
2021-09-14 13:13:39 +01:00
45734d882c [CONFIG] Make it possible to write module configuration in a config.{php,yml,yaml,xml} file and set each value as properties in the module object 2021-09-14 13:13:38 +01:00
6ef07e04d1 [Posting][CSS] Right panel form uses a select box instead of radio buttons. Hover and focus of <a> elements using just an underline. Note author and actions padding redone. File-picker font is now correct. Left panel hierarchy should now be more clear. 2021-09-14 13:13:38 +01:00
7dc390ca1c [TWIG][CSS] Shortcuts now work in small screen sizes. Header icons further polish. Profile navigation structural rework. 2021-09-14 13:13:38 +01:00
ca2eff2906 [CSS] Visual feedback from shortcuts polished. 2021-09-14 13:13:38 +01:00
414b33f97b [TWIG][CSS] Shortcut menu done. Can access various panel with proper visual feedback. 2021-09-14 13:13:38 +01:00
e73af2b887 [TWIG][CSS] Left and Right panels now using a checkbox trick to control their visibility. Details element couldn't be properly controlled by CSS without breaking accessibility. 2021-09-14 13:13:38 +01:00
6e6b2ea87b [CSS][Icons] Icons width and height wasn't consistent, problem lied within the SVGs themselves. 2021-09-14 13:13:38 +01:00
b8bb845e24 [TWIG][CSS][Accessibility] Note view accessibility improvements. Left and right panels icon rework (width and height weren't correct, position needs further work). 2021-09-14 13:13:38 +01:00
d2760f1250 [TWIG][CSS][Accessibility] Base template accessibility improvements. Applying more semantic HTML5 tags and aria to describe content actions. 2021-09-14 13:13:38 +01:00
671e2d6a9d [CSS] Fixed Favourite button background size and colour. Fixed right panel incorrect font size. 2021-09-14 13:13:37 +01:00
8880af8197 [ActivityStreamsTwo] Introduce a structure for data representation in ActivityStreams 2.0
Type factory borrowed from landrok/activitypub
2021-09-14 13:13:37 +01:00
e4aa3ae968 [NOTE] Add route and controller 2021-09-14 13:13:37 +01:00
fd3b57dc24 [CORE][Controller] Make it possible for plugins to add different content-types to existing routes 2021-09-14 13:13:37 +01:00
8e45637277 [DOCS][User] Elaborate on what is GNU social and IndieWeb 2021-09-14 13:13:37 +01:00
626f50080b [MODULES] Use snake_case for module config keys 2021-09-14 13:13:37 +01:00
033c4db914 [MODULES] Add function to defer module initialization and cleanup to plugin and component. Add example in Avatar component
Forward onInitializeModule to onInitializePlugin if the component is a plugin
2021-09-14 13:13:37 +01:00
bda839be7b [MODULES] Add InitiializeModule and CleanupModule events, similar to v2 2021-09-14 13:13:37 +01:00
1ee8df1494 [DOCS][Developer] Elaborate on implementing and configuring a module 2021-09-14 13:13:37 +01:00
141f919ca7 [CONFIG][TESTS] Fix error found by AdminPanel test 2021-09-14 13:13:36 +01:00
4d3da08b1e [CONFIG] Add example module configuration 2021-09-14 13:13:36 +01:00
c71a4b06ef [CONFIG] Make it possible to write module configuration in a config.{php,yml,yaml,xml} file and set each value as properties in the module object 2021-09-14 13:13:36 +01:00
3587b8dc1d [CONFIG] Refactor configuration loading 2021-09-14 13:13:36 +01:00
c94ef26617 [TESTS] Fix namespace on Controller Security test 2021-09-14 13:13:36 +01:00
56e5d5c4a0 [TESTS] Fix broken tests and expand tests around Attachments 2021-09-14 13:13:36 +01:00
f1bd4db495 [TESTS] Fix Common test 2021-09-14 13:13:36 +01:00
2fdd0b0820 [TESTS][DataFixtures] Use Temporary file instead of an ad-hoc solution to copy the upload files 2021-09-14 13:13:36 +01:00
9739cc5f21 [Posting] Respect process_links setting 2021-09-14 13:13:36 +01:00
ab142ab52d [FileQuota] Update plugin to respect the new entities 2021-09-14 13:13:35 +01:00
2b457655ea [CORE] Fix path configuration 2021-09-14 13:13:35 +01:00
e7b985a460 [FIXTURES] Catch any exception, we don't have VIPS-related only 2021-09-14 13:13:35 +01:00
aa8412f607 [TESTS][Forms] Respect new naming conventions 2021-09-14 13:13:35 +01:00
9067bd8785 [TESTS] remove accidentally duplicate sample upload 2021-09-14 13:13:35 +01:00
415089914f [VideoEncoder] Port plugin to v3 properly 2021-09-14 13:13:35 +01:00
5107e06fae [DOCS][Developer] Paradigms: Update is_null based on poll votes
Everything around the use we give to php's null is about the state of having a value or not. Thus, using `is_null` always is the less bad option.
2021-09-14 13:13:35 +01:00
2b7232891e [ImageEncoder] Make plugin respect instance config and use the new core interface 2021-09-14 13:13:35 +01:00
f9079784c4 [ENTITY][AttachmentThumbnail] Improve the way EncoderPlugins participate in the thumbnail process 2021-09-14 13:13:35 +01:00
e4b2821657 [TWIG][Attachments] Don't throw event with mimetype in its name 2021-09-14 13:13:35 +01:00
bc1fb007aa [Core][GSFile] Improve the way EncoderPlugins participate in the file sanitization process 2021-09-14 13:13:34 +01:00
210f895e74 [ENTITY][Attachment] Respect rfc6838#section-4.2 mimetype length 2021-09-14 13:13:34 +01:00
e80ad2d87b [TESTS][Controller][AdminTest] Update int tests to use attachment file_quota instead, as we deleted attachment max width 2021-09-14 13:13:34 +01:00
b0b4f37078 [CONFIG] Add setting for attachment sanitization 2021-09-14 13:13:34 +01:00
2a3db65216 [CONTROLLER][Attachment] Some attachments may not have dimensions 2021-09-14 13:13:34 +01:00
450dbfb98f [DOCUMENTATION] Update documentation regarding route accept formats 2021-09-14 13:13:34 +01:00
26bf78360b [ROUTER][UTIL] Allow specifying the Accept format for a route 2021-09-14 13:13:34 +01:00
86bdc398c5 [DOCKER] Update PHP docker container to include ffmpeg, for the VideoEncoderPlugin 2021-09-14 13:13:34 +01:00
811caaadf9 [MODULES][PLUGINS] Move noteActionHandle utility to NoteHandlerPlugin which plugins which handle actions on notes should extend 2021-09-14 13:13:34 +01:00
458b6d0009 [UI] Rename all forms to more specific names, to avoid form name collisions 2021-09-14 13:13:33 +01:00
6af1383e07 [UTIL][Form] Disallow using very generic form names, as they can collide with other forms in the same page 2021-09-14 13:13:33 +01:00
a7d5b5599c [TESTS] Fix LocalUserTest, i forgor to boot the kernel 2021-09-14 13:13:33 +01:00
e278efe61d [TESTS] Fix tests broken with rebased commits 2021-09-14 13:13:33 +01:00
8e12f5ee59 [TESTS] Raise test coverage for Link to 100% 2021-09-14 13:13:33 +01:00
c78032f1fa [TESTS] Raise test coverage of LocalGroup to 100% 2021-09-14 13:13:33 +01:00
cfc89d8a25 [TESTS] Raise test coverage of LocalUser to 100% 2021-09-14 13:13:33 +01:00
a2e302efb4 [TESTS] Raise GSActor test coverage to 100% 2021-09-14 13:13:33 +01:00
043e179c23 [TESTS][Attachment][AttachmentThumbnail][GSFile] Reorganize tests and raise test coverage to 100% 2021-09-14 13:13:33 +01:00
4cd3924cc1 [ATTACHMENTS][AttachmentThumbnail] Fix implementation of predictScalingValues and small fixes 2021-09-14 13:13:32 +01:00
2ccbbd53a6 [TESTS] Add code coverage annotations to entities 2021-09-14 13:13:32 +01:00
e7699b3245 [TESTS] Raise test coverage for Note to 100% 2021-09-14 13:13:32 +01:00
79215bc439 [Note] Fix scope check for group notes, move away from SQL, to DQL 2021-09-14 13:13:32 +01:00
e392a9c90c [TESTS][DataFixtures] Add user, self follows, group member and group scope note 2021-09-14 13:13:32 +01:00
365afb7ba8 [TOOLS] Disable command echo in Makefile 2021-09-14 13:13:32 +01:00
4b2a92d052 [UI][Attachment] Use Attachment methods to get the proper URL, rather than crafting it in a template 2021-09-14 13:13:32 +01:00
6799052ff5 [ATTACHMENTS] Ensure thumbnail dimensions are bounded and change way cropping is implemented 2021-09-14 13:13:32 +01:00
f67173061b [VideoEncoder] Add plugin composer dependency php-ffmpeg/php-ffmpeg 2021-09-14 13:13:32 +01:00
ac45008240 [Embed] Move composer dependency embed/embed from core to plugin 2021-09-14 13:13:31 +01:00
b50f11a040 [ENTITY][Link] self urls can't be considered a remote url 2021-09-14 13:13:31 +01:00
177801c81b [Embed][StoreRemoteMedia] Re-add {white,black}list check config 2021-09-14 13:13:31 +01:00
de444a2a5a [Posting] Fix wrong usage of DB::findBy 2021-09-14 13:13:31 +01:00
e40c7b0509 [DOCS][Developer] Recommend reading the tests cases for when the doc doesn't cover 2021-09-14 13:13:31 +01:00
5c8677304c [DOCS][Developer] Update storage documentation 2021-09-14 13:13:31 +01:00
78f4ccb576 [ImageEncoder] Fix ImageSanitization, it should never modify the input image 2021-09-14 13:13:31 +01:00
ca71e57593 [CSS] Hotfix: Figure captions do not overflow. 2021-09-14 13:13:31 +01:00
41b42407cd [Posting] Store uploaded filenames as titles 2021-09-14 13:13:31 +01:00
036e9cb58e [Avatar] Preserve uploaded filename and use Avatar's own route instead of attachment 2021-09-14 13:13:30 +01:00
f70eb8f12d Remove weird empty template 2021-09-14 13:13:30 +01:00
6166afeec6 [TWIG][CSS] Left and right panels accessibility improvements. Tabindex is now properly set up. When panels have the attribute open but aren't focused (keyboard navigation out of panel, into main content) they aren't displayed anymore. 2021-09-14 13:13:30 +01:00
e2e6c7a5bf [TESTS] Hot-fix Security controller tests, broken with ongoing form rendering changes 2021-09-14 13:13:30 +01:00
c81795eb96 [TWIG][CSS] More consistent classes. Checkbox styling done. Register and Login pages now done. 2021-09-14 13:13:30 +01:00
44a581f0f6 [UTIL][FORM] Password form now shows the proper HTML class, and it's respective label. 2021-09-14 13:13:30 +01:00
87d7318de5 [CONTROLLER][SECURITY] Added class names. Help labels for each form element. Each form element now has a proper block prefix (the resulting HTML won't simply concatenate the form's name to the element's label). 2021-09-14 13:13:30 +01:00
ab10cd4121 [DOC] Fixed installation.md typos. 2021-09-14 13:13:30 +01:00
ebee70621b [FORM] Fix bug where options were passed in the data parameter 2021-09-14 13:13:30 +01:00
1419035076 [DOCS][Developer] Add an introduction 2021-09-14 13:13:29 +01:00
afd00fbdc5 [DOCS][Developer] httpclient: Add an example of lazyness care 2021-09-14 13:13:29 +01:00
31ca5cb35e [DOCS][Developer] Paradigms: apply XRevan86 fixes and remove the return types section, we must revisit it later.. 2021-09-14 13:13:29 +01:00
54e03d49d4 [DOCS][Developer] Remove low level index, we will approach these themes in another manner
Fix some broken links
2021-09-14 13:13:29 +01:00
c8e00e4187 [TOOLS] Add make command 'database-force-schema-update' to update the database schema and 'redis-shell' 2021-09-14 13:13:29 +01:00
8ca61eea77 Duplicate public/assets/css/bg.jpg history in tests/sample-uploads/attachment-lifecycle-target.jpg history. 2021-09-14 13:13:29 +01:00
6d7a0dbc92 [TESTS][TOOLS] Always stop containers regardless of test success 2021-09-14 13:13:29 +01:00
5410f22060 [DEPENDENCIES] Update dependencies 2021-09-14 13:13:29 +01:00
4f880eb761 [PLUGINS][ENTITY][Cover][ProfileColor] Clean up after interns and move entity defintions to be inside the corresponding plugin, rather than in core 2021-09-14 13:13:29 +01:00
5237364a21 [TESTS] Raise test coverage for GSFile to 100% 2021-09-14 13:13:28 +01:00
300eccfd17 [TESTS] Raise test coverage for Attachment controller to 100% 2021-09-14 13:13:28 +01:00
2351e7c6d1 [CORE][GSFile] Use pathinfo rather than regular expressions and don't attempt to persist an already persisted entity 2021-09-14 13:13:28 +01:00
3843348c1b [CONTROLLER][Attachment] Small refactor and add testing annotation 2021-09-14 13:13:28 +01:00
e2caf19b67 [TESTS] Remove copied upload test files, if upload failed 2021-09-14 13:13:28 +01:00
aef61e4c73 [TESTS] Add coverage ignore flags to trivial methods 2021-09-14 13:13:28 +01:00
fe86735b8b [DB][DOCUMENTATION] Explain limit: 2 in findOneBy 2021-09-14 13:13:28 +01:00
c3db2f60d2 [UTIL][EXCEPTIONS] Introduce NotStoredLocallyException 2021-09-14 13:13:28 +01:00
6445a616a8 [ENTITY][Attachment] Raise mimetype max length to 64 characters and ensure we don't attempt to store more than that 2021-09-14 13:13:28 +01:00
d4d4f4e950 [TESTS] Cleanup attachment test data 2021-09-14 13:13:27 +01:00
6e6d1a946f [TESTS] Remove MediaFileTest and move setup code to media data fixture 2021-09-14 13:13:27 +01:00
53f89ade85 [TESTS] Move Media fixtures to their own file, for organization 2021-09-14 13:13:27 +01:00
74d1874991 [DOCUMENTATION][Entity] Improve documentation on Entity::getWithPK, explaining the ways it can be used 2021-09-14 13:13:27 +01:00
060a5abef1 [ENTITY][Link] Sometimes URLs don't work, handle that 2021-09-14 13:13:27 +01:00
1906d4f276 [Embed] Add UI element and fix some bugs 2021-09-14 13:13:27 +01:00
061c953eac [TWIG] Add Links representation to notes 2021-09-14 13:13:27 +01:00
ef1a9ce3b1 [ImageEncoder] Handle VIPS unsupported image type 2021-09-14 13:13:27 +01:00
f690bc06ae [ATTACHMENT] Some attachments don't have thumbnails and that's okay 2021-09-14 13:13:27 +01:00
b4a03b814f [CORE][GSFile] ensureFilenameWithProperExtension: extension isn't an I/O param 2021-09-14 13:13:26 +01:00
728f8d8fb8 [ENTITY][Note] Add getter for note links 2021-09-14 13:13:26 +01:00
9e4cac0123 [ENTITY] Refactor RemoteURL entities to Link
RemoteURL was being an awfully confusing term.
2021-09-14 13:13:26 +01:00
fb28a3656a [Embed] Retrieve remote thumbnails and other improvements 2021-09-14 13:13:26 +01:00
7a0a6f1f22 [Embed] Fix usage of EmbedLib
Fix other minor bugs
2021-09-14 13:13:26 +01:00
968e3431e1 [Attachment] Sometimes we can't provide download of original file 2021-09-14 13:13:26 +01:00
4cc4523632 [Posting] Re-add original file to attachment on upload, if it was previously removed 2021-09-14 13:13:26 +01:00
d076781c74 [AttachmentToNote][Attachment] Add title getter to Attachment 2021-09-14 13:13:26 +01:00
5fd91bf3a2 [TESTS][Twig] Fix ExtensionTest->testIconsExtension 2021-09-14 13:13:26 +01:00
bac18715c5 [StoreRemoteMedia] Implement the first version of it in v3 2021-09-14 13:13:25 +01:00
63cbf4052f [UTIL] Common::config wasn't a proper port from v2, it has to accept one argument only as well 2021-09-14 13:13:25 +01:00
33cc9386d2 [RemoteURLToAttachment] Fix primary key, relation is: One Attachment Has Many URLs, One URL Has One Attachment 2021-09-14 13:13:25 +01:00
78c5c4b084 [Attachment] Allow to delete the associated file 2021-09-14 13:13:25 +01:00
508f1f8796 [MODULES] Add module configuration 2021-09-14 13:13:25 +01:00
de8a2f579c [CORE][Event] Fix bug on handler Log 2021-09-14 13:13:25 +01:00
4ecdeac6a3 [CORE][Entity] Compare with object properties when creating/updating, instead of class 2021-09-14 13:13:25 +01:00
75f70f8182 [ENTITY][Posting] Remove GSActorToRemoteURL, Fix URL database store 2021-09-14 13:13:25 +01:00
fbbbde4275 [AttachmentShowRelated] Bug fix after re-introduction of NoteActions 2021-09-14 13:13:25 +01:00
df62d7e4f4 [CSS][Assets] Minified header icons. Reverted footer links position due to Firefox's corageous interpretation of a fixed element's position. 2021-09-14 13:13:25 +01:00
5de0704de2 [Favourite][TWIG][CSS] Favourite shows alt-text and properly sets colours. Titles translated on the right panel. 2021-09-14 13:13:24 +01:00
f5175cc59d [ATTACHMENTS] Always store in the same location 2021-09-14 13:13:24 +01:00
3f61537140 [ENTITY] Split Attachment in various new entities
Remove Attachment Scope
Fixed some minor bugs

Scope will be implemented later in v3. It doesn't make sense to have
the scope handling being per attachment. Different actors can post
the same attachment with different scopes. The attachment controller
will assume the highest level of scope applied to the attachment and
the rest will be handled at the note level.

Motivation:
* Remove title from attachment, as it's part of the relation between attachment and note.
* Remove actor from attachment, many actors may publish the same attachment.
* Remove is_local from attachment,  as it's part of the relation between attachment and note.
* Remove remote_url from attachment, different urls can return the same attachment.

Addition:
* Attachment now has a lives attribute,  it's a reference counter with a nicer name
* GSActorToAttachment
* GSActorToRemoteURL
* RemoteURL
* RemoteURLToNote
* RemoteURLToAttachment
* AttachmentToNote now has a title attribute
2021-09-14 13:13:24 +01:00
a7c8da0534 [FileQuota] We'll get back to this plugin later 2021-09-14 13:13:24 +01:00
39006fb6b5 [DB][Attachments] Use count function rathar than fetch and count, rename to refCount, rather than countDepencies 2021-09-14 13:13:24 +01:00
8880405dee [DEPENDENCIES] Update dependencies 2021-09-14 13:13:24 +01:00
809bf00aa9 [TemporaryFile][TESTS] Throw on attempt to write to null resource and fix tests 2021-09-14 13:13:24 +01:00
c24c32334d [TESTS] Add test for JSON response and invalid accept format 2021-09-14 13:13:24 +01:00
6728dd40b0 [ENTITY] Add JsonSerializable interface to Entity base class and implement it for the Note class 2021-09-14 13:13:24 +01:00
2851b899b8 [TESTS] Add test annotations to core classes 2021-09-14 13:13:23 +01:00
21a5bbe639 [CORE][Controller] Fix JSON response and add test annotations 2021-09-14 13:13:23 +01:00
061a85d6b3 [EVENTS] Change FormatNoteList do separate in and out arguments
This is necessary due to some weird problem which I wasn't able to figure out (but which doesn't matter)
that somehow causes the event to be called twice during testing, and thus the function was exploding
2021-09-14 13:13:23 +01:00
57f43108bb [TESTS] Fix Entity test in accordance with the changes to createOrUpdate 2021-09-14 13:13:23 +01:00
b5de80303a [TEST] Raise test coverage for UserPanel to 100% 2021-09-14 13:13:23 +01:00
480665afc8 [CONTROLLER][UserPanel] Finish implementation of ::notifications so it actually saves the values in the database 2021-09-14 13:13:23 +01:00
cdf3426567 [CONTROLLR][UserPanel][PLUGINS] Add submit button to notification settings for each transport 2021-09-14 13:13:23 +01:00
afbcb179b2 [CONTROLLER][AdminPanel] Further ensure form validity 2021-09-14 13:13:23 +01:00
38a331220f [CORE][Log] Add Log::unexpected_exception utility which logs and throws a ServerException 2021-09-14 13:13:23 +01:00
085e880631 [CORE][Entity] Fix implementation of createOrUpdate so it doesn't throw NotFoundException if trying to create an object
This was previously done because we wanted to notify the callee that
and entity existed but not with the provided contents. With the change
of return value, with a bool $is_update, this is no longer a problem.
2021-09-14 13:13:22 +01:00
662ad8e9cf [TESTS] Update PHPUnit config to start executing tests by last failure. This doens't seem to actually work currently, though 2021-09-14 13:13:22 +01:00
11e52bcb27 [TOOLS] Add utility commands to the Makefile 2021-09-14 13:13:22 +01:00
1b623a85ae [UTIL][FormFields] Move FormFields class to Util\Form namespace 2021-09-14 13:13:22 +01:00
1647c5391f [Favourite][TWIG][CSS] Favourite now works. 2021-09-14 13:13:22 +01:00
e15044fe36 [CSS] Overall typography resizing to provide proper text hierarchy. Radio buttons polish, notes author box is now smaller. Better organization of CSS rules according to their filename and thus, their aim. 2021-09-14 13:13:22 +01:00
1962a004aa [CSS] Fixed top margin, footer elements are now actually footer elements. 2021-09-14 13:13:22 +01:00
e180143e20 [TWIG][CSS] Buttons are now the correct size in all contexts. Right panel create a notice section re-structure. 2021-09-14 13:13:22 +01:00
cb21599cef [TWIG][CSS] Feedback provided to active page. Removed top accent border on notes. 2021-09-14 13:13:22 +01:00
68cf6dee65 [FAQ][CSS] All FAQ pages stylized, minor structure changes throughout. 2021-09-14 13:13:22 +01:00
10f930ad4b [TWIG][CSS] Left panel text hierarchy fix (no <hr> element between timeline navigation and its items). Default CSS fixes for buttons and input file selectors. 2021-09-14 13:13:21 +01:00
0f032c257b [CSS] Input file elements polish. It should resize properly and provide feedback when selected (not a thing in Firefox ESR yet). 2021-09-14 13:13:21 +01:00
bac6d2a490 [CSS] Base CSS polish, reset CSS additions for better cross-browser compatibility. 2021-09-14 13:13:21 +01:00
a77f51dd06 [Avatar] Delete attachment only if safe 2021-09-14 13:13:21 +01:00
21362d1e4d [ATTACHMENTS] Add dependencies counter 2021-09-14 13:13:21 +01:00
95fd86f8dc [CSS] Fixed background incorrect sizing. 2021-09-14 13:13:21 +01:00
d0b2cccb63 [CSS] Mesh gradient works as intended with no banding. 2021-09-14 13:13:21 +01:00
0c612bddbe [Avatar] Store as regular attachments 2021-09-14 13:13:21 +01:00
b355f0d590 [DEV] Add PsySH REPL 2021-09-14 13:13:20 +01:00
3334aca7b9 [Avatar] Move entity from core to component 2021-09-14 13:13:20 +01:00
fb6aa78ae8 [CORE][GSFile] Allow storing files under /file 2021-09-14 13:13:20 +01:00
e688bf8aed [TESTS] Ignore coverage of ResetPasswordRequest, as it uses mailing functionality. We may want to introduce this test in the future 2021-09-14 13:13:20 +01:00
9ad2cb5e66 [UTIL][FormFields] Allow specifying whether a password is required and provide placeholder text 2021-09-14 13:13:20 +01:00
5aedf64e5b [ROUTES] Remove individual settings pages, as they got merged 2021-09-14 13:13:20 +01:00
27f2fbdade [ENTITY] Refactor LocalUser::changePassword for easier use 2021-09-14 13:13:20 +01:00
19318b3163 [UTIL][EXCEPTION] Add AuthenticationException, representing an auth error, status code 401 unauthorized 2021-09-14 13:13:20 +01:00
a1592656e0 [TESTS] Change format of data fixtures to allow creating more users 2021-09-14 13:13:20 +01:00
2dd3511149 [CORE][DB] Specify desired case in array_change_case, for clarity 2021-09-14 13:13:19 +01:00
0ae67d96ea [TESTS] Raise test coverage for AdminPanel to 100% 2021-09-14 13:13:19 +01:00
b77e35ef09 [SECURITY] Do not require email when in development 2021-09-14 13:13:19 +01:00
e8ef777fb2 [DOCS][Dev] Add Debugging and Testing 2021-09-14 13:13:19 +01:00
8240591bd4 [TESTS] Fixup Security controller tests to match new UI 2021-09-14 13:13:19 +01:00
fe7c2b5115 [TESTS] Raise test coverage for AdminPanel controller to 100% 2021-09-14 13:13:19 +01:00
e0a0df502e [TESTS] Raise test coverage for Attachment controller to 100% 2021-09-14 13:13:19 +01:00
29d77b446f [TESTS] Add a sample image to the test dataset 2021-09-14 13:13:19 +01:00
647e4c03b3 [CORE][GSFile] Ensure files are stored inside the configured storage folder, with a relative filename in the database 2021-09-14 13:13:19 +01:00
51f8f004b3 [CORE][CONTROLLER] Add TODO to Controller base class as to where our custom exception pages would be implemented 2021-09-14 13:13:18 +01:00
0b80727769 [CORE][ENTITY] Allow create'ing will null values 2021-09-14 13:13:18 +01:00
77742c56c3 [ImageEncoder] Don't print_r the exception as that leads to an OOM error 2021-09-14 13:13:18 +01:00
4aee27d3a6 [CONFIG] Ensure consistency in config file 2021-09-14 13:13:18 +01:00
229a516fd2 [TESTS] Make PHPUnit exit on first fail and some other tweaks 2021-09-14 13:13:18 +01:00
855d427442 [UTIL][FORM] Create a utility class that defines common form fields, such as passwords 2021-09-14 13:13:18 +01:00
dfc97d2607 [TESTS] Raise test coverage for Controller/Security to 100% 2021-09-14 13:13:18 +01:00
dc2b9f940e [CORE][GSFile] Assert that the destination folder where to store the attachment is inside the INSTALLDIR and store the filepath in the database 2021-09-14 13:13:18 +01:00
8139a21eb9 [TESTS] Add coverage ignore to TemplateController and ResetPassword (as it requires sending emails) 2021-09-14 13:13:18 +01:00
518995d155 [CONTROLLER][Attachment] Assert that the supplied is positive and add documentation 2021-09-14 13:13:17 +01:00
88dd9e542f [CORE][GSFile] Change actor_id paramenter of validateAndStoreFileAsAttachment to optional and reorder them and their usages 2021-09-14 13:13:17 +01:00
7bd88bd101 [AUTOGENERATED] Update entity fields for ResetPasswordRequest entity 2021-09-14 13:13:17 +01:00
471dc52c92 [CORE] Add repositories, as needed by the Reset Password Bundle 2021-09-14 13:13:17 +01:00
0c54a3297f [UTIL] Add a class that defines commonly used form fields 2021-09-14 13:13:17 +01:00
ccd5ebf8e4 [CORE] Add passowrd reset and forgot password functionality 2021-09-14 13:13:17 +01:00
c3d2f04841 [DEPENDENCIES] Add symfonycasts/reset-password-bundle as a dependency 2021-09-14 13:13:17 +01:00
769fff2448 [CORE][SECURITY][EMAIL] Move email confirmation functionality to it's own static wrapper, in preparation for adding password reset functionality 2021-09-14 13:13:17 +01:00
e27823ae6c [CONTROLLER][Security] Refactor and make clearer errors with duplicate nicknames and emails. Return notes as a callable, since they're not used in the default template, in the login and register pages 2021-09-14 13:13:17 +01:00
32ca61e214 [TESTS][Queue] Add @codeCoverageIgnore to select queueing functions 2021-09-14 13:13:16 +01:00
41e4e2de0e [TESTS][Router] Add tests for Router and use named paramenters, as we can since PHP8 2021-09-14 13:13:16 +01:00
6d22932092 [ENTITY][LocalUser] Add method 'findByNicknameOrEmail' 2021-09-14 13:13:16 +01:00
e6d20bd30d [CORE][Controller][TESTS] Fix issue that arrises in tests where the Accept header is not specified 2021-09-14 13:13:16 +01:00
d07cb79844 [EXCEPTION] Add Email related exceptions 2021-09-14 13:13:16 +01:00
e250edf7fd [UTIL][Nickname] Refactor Nickname and extract a validate function, as we'll want to perform normalization in select cases in the future, likely as a plugin 2021-09-14 13:13:16 +01:00
1521d0d823 [UI] Add TODO annotation to login template, since it's possible to login using email, so the fonrm field names should be updated 2021-09-14 13:13:16 +01:00
f904b76ce7 [TESTS][DataFixtures] Add password and email to created test user 2021-09-14 13:13:16 +01:00
efacf6da56 [TESTS][Twig] Add @codeCoverageIgnore to select methods, as these are simple wrappers 2021-09-14 13:13:16 +01:00
1d40c5cdb3 [TESTS][DB] Update test to reflec fact that GSActor no longer has a normalized_nickname field 2021-09-14 13:13:15 +01:00
6b4b3e90fb [TESTS][Nickname] Update tests to reflect new usage. Normalization functionality will be moved to a plugin 2021-09-14 13:13:15 +01:00
adf0897527 [TESTS][TemporaryFile] Update test to reflect new usage 2021-09-14 13:13:15 +01:00
e77498ac19 [ENTITY] Remove 'normalized_nickname' field from GSActor as that feature will be moved to a plugin 2021-09-14 13:13:15 +01:00
2f69579ddb [TESTS][DOCUMENTATION][Module] Add documentation and exclude method from testing in Module base class 2021-09-14 13:13:15 +01:00
7a2574eafb [CORE][TemporaryFile] Add option to specify attempts and better handle when reaching the attemp limit without being able to create a file 2021-09-14 13:13:15 +01:00
f5fb4ed3c3 [TESTS] Add tests for GSFile 2021-09-14 13:13:15 +01:00
af5526d720 [DB] Refactor findOneBy method 2021-09-14 13:13:15 +01:00
7263752b18 [TESTS][DOCUMENTATION] Add documenation for the list events command and exclude it from unit testing 2021-09-14 13:13:15 +01:00
1c09aefd5a [CONFIG] Make password length limits configurable 2021-09-14 13:13:14 +01:00
6a74102d52 [TESTS] Exclude Data Fixtures from testing, as that happens before testing 2021-09-14 13:13:14 +01:00
de5650e98e [TESTS] Exclude class Security from testing, as it's a simple wrapper 2021-09-14 13:13:14 +01:00
d609dafdbc [TESTS] Raise test coverage for ModuleManager to 100% 2021-09-14 13:13:14 +01:00
bd321f05a7 [TESTS] Exclude HTTPClient from testing, as it's a simple wrapper and we don't want to be performing HTTP requests in tests, for speed and reliability 2021-09-14 13:13:14 +01:00
2ee99e5176 [TESTS] Raise test coverage for Form to 100% 2021-09-14 13:13:14 +01:00
0f634e86c7 [TESTS] Revert exposing Redis docker container ports, as this conflicts with the actual instance, and was intended for testing 2021-09-14 13:13:14 +01:00
b111870853 [TESTS][EVENTS] Raise test coverage for Event class to 100% 2021-09-14 13:13:14 +01:00
871422e6b6 [TESTS][ENTITY] Raise test coverage for Entity class to 100% 2021-09-14 13:13:14 +01:00
3b18853ff1 [TESTS][LOG] Raise test coverage for Log class to 100% 2021-09-14 13:13:14 +01:00
f98ce1c3d0 [TESTS] Ignore GNUsocial class from tests, as it simply pipes objects around 2021-09-14 13:13:13 +01:00
3cc1756d1b [FORM][DOCUMENTATION] Add documentation to Form class 2021-09-14 13:13:13 +01:00
f9a022745e [EVENT] Fixup implementation, as imformed by tests 2021-09-14 13:13:13 +01:00
d22711504c [ENTITY] Fixup implementation, as imformed by tests 2021-09-14 13:13:13 +01:00
8317c612ff [DB] Handle using methods with class name as well as table name and add lookup methods 2021-09-14 13:13:13 +01:00
747b464c7d [TESTS] Add missing tests for Common 2021-09-14 13:13:13 +01:00
9ce30751af [TESTS] Expand and fix cache tests 2021-09-14 13:13:13 +01:00
bfe9c6c9c4 [TESTS] Add ignore annotations to code paths that serve as hooks in DependencyInjection 2021-09-14 13:13:13 +01:00
28c010fcc7 [TESTS][CACHE] Fixup errors found in cache implementation by testing. Ensure the newest values are kept, in pushList with max_count 2021-09-14 13:13:12 +01:00
e2f61b05d8 [ENTITY] Fix foreign key type in Cover entity, as found by tests 2021-09-14 13:13:12 +01:00
a8081854c2 [TESTS] Exclude Routes from testing, as well as, temporarily, src/Security 2021-09-14 13:13:12 +01:00
88f1437ee7 [TESTS] Use vendor/bin/simple-phpunit for running the tests, as it provides the appropriate polyfills 2021-09-14 13:13:12 +01:00
082656d1ae [LEFT][RIGHT][CSS] Panels now occupy full page in smaller screen sizes. 2021-09-14 13:13:12 +01:00
bd9e86afe0 [RIGHT][CSS] Right panel now shows an intuitive icon for other note options available. 2021-09-14 13:13:12 +01:00
625c056f30 [TWIG][CSS] Overall CSS optimizations. Image gradients are now used, 64x64 px. 2021-09-14 13:13:12 +01:00
c8a8e94d48 [SETTINGS][PLUGIN][CONTROLLER] Populate profile tabs event added. Settings base template populated with such event for plugins and components.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:12 +01:00
6dd0292397 [SETTINGS][ROUTES][CONTROLLER] Settings overhaul, refactoring to accommodate new global settings view. WIP, component settings aren't shown at the moment.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:12 +01:00
eed74972c5 [SETTINGS][TWIG][CSS] Settings WIP. Form polished, dropdowns need styling.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:12 +01:00
d12f97c623 [BASE][CSS] Snappier and consistent animations.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:11 +01:00
10d7462d02 [TWIG][SETTINGS] WIP. Settings navigation early sketch.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:11 +01:00
a6f5c61aef [CSS] <figcaption> now has top padding for better legibility, hover now resizes it's element accordingly.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:11 +01:00
d16614982a [TWIG][CSS] Panels are fixed and base content acts accordingly on all sizes.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:11 +01:00
7b6a44cfbb [DOCS][Dev] Add HTTP Client 2021-09-14 13:13:11 +01:00
c99e447308 [DOCS][Dev] Add Security 2021-09-14 13:13:11 +01:00
367cc5c5c7 [DOCS][Dev] Add Queues 2021-09-14 13:13:11 +01:00
27fb2da1d0 [DOCS][Dev] Add Internationalisation 2021-09-14 13:13:11 +01:00
3dffbdd0b7 [DOCS][Dev] Add Attachments 2021-09-14 13:13:11 +01:00
2473c9afa9 [DOCS][Dev] Configure search 2021-09-14 13:13:10 +01:00
70ab7e7af7 [DOCS][Dev] Add Logging 2021-09-14 13:13:10 +01:00
ef827db77c [DOCS][Dev] Add Templates 2021-09-14 13:13:10 +01:00
ce39f6ca4a [DOCS][Dev] Add Routes and Controllers 2021-09-14 13:13:10 +01:00
0c6088225f [DOCS][Dev] Add Cache 2021-09-14 13:13:10 +01:00
b60a07f270 [DOCS][Dev] Cleanup src directory 2021-09-14 13:13:10 +01:00
9baf3a3124 [DOCS][Dev] Add database chapter 2021-09-14 13:13:10 +01:00
ad49988e0b [DOCS][DEV] Add events 2021-09-14 13:13:10 +01:00
2be4aeaab2 [DOCS][Paradigms] Elaborate on Null, Set and Void 2021-09-14 13:13:10 +01:00
c020958690 [DOCS] Write exceptions chapter 2021-09-14 13:13:09 +01:00
75bbf6c728 [TWIG][CSS] Final fix for panels, resizing works as intended, content is wrapped when no space is available. Simpler rules throughout.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:09 +01:00
ce06c1dfd2 [TWIG][CSS] Panels weren't "flexing" properly, in smaller sizes the right panel form would break.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:09 +01:00
e546721ca1 [TWIG][CSS] Fixed right panel buttons, fix issue where the form was invalid on send.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:09 +01:00
203b16c5bf [TWIG][CSS] Right panel WIP. Create a note now looks better, need to style in some way the default user agent buttons without removing features (e.g. current file chosen).
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:09 +01:00
4805550c66 [TWIG][CSS] Left panel profile section done.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:09 +01:00
9d50289c3f [TWIG][CSS] Register and Login styling done.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:09 +01:00
5e31e3290d [CSS] Fixing poor responsiveness to main nav element hover animation.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:09 +01:00
e0a14f0b86 [CSS][TWIG] Left panel HTML nesting to better aid screen readers.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:09 +01:00
cd05589f67 [CSS][TWIG] Panels icons are now hidden on desktop view to stop possible inconsistencies on window resizing. Left Panel polish.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:09 +01:00
2bae14198b [CSS][TWIG] Details element is now shown by default on larger screens, and hidden on smaller screens.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:08 +01:00
e5649d82ba [CSS][TWIG] Timeline navigation is now a part of the left panel, this way more items could be displayed at a time. Left panel styling WIP.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:08 +01:00
22f394f28f [TWIG] Microformats added to timeline, note's view and media. Should be backwards compatiblr as well.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:08 +01:00
03fb7b43e8 [CSS] Fixed accessibility issues with header and panel elements. Left, instance and right elements are now properly ordered when focused.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:08 +01:00
8bff04dae1 [CSS] Fixed incorrect Chromium based browsers improper main content view. Flex item order (shouldn't be a problem, but it was) and padding for the container class was the root issue.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:08 +01:00
7f561376ac [CSS] Main container 'order' attribute was somehow a problem in Chromium. 2021-09-14 13:13:08 +01:00
8b5f08a4bd [CSS] Fixed top content margin. 2021-09-14 13:13:08 +01:00
c06e666816 [TWIG][CSS] Accessibility improvements, all general links provide proper feedback now. Base theme CSS progress, page now looks more as it should. Panels WIP. 2021-09-14 13:13:08 +01:00
98e7e94dfa [TWIG][CSS][ICONS] New profile and notice creation panel, alternative text set correctly for header icons. WIP in base styling and panels. 2021-09-14 13:13:07 +01:00
868dbbd44e [TWIG][CSS] Found solution to show details content by default in desktop view. However, post_form is being rendered multiple times, it was already rendered in the Posting Component. Needs to be fixed. 2021-09-14 13:13:07 +01:00
9519891b92 [TWIG][CSS] Panels are now animated when shown, main content width as well as panel's is now correctly configured. WIP: displaying side panels by default when space is available, "details" element state cannot be manipulated through CSS only, need a better solution. 2021-09-14 13:13:07 +01:00
95c81cc741 [TWIG][CSS] Panels functionality works as intended, size needs to be worked upon. 2021-09-14 13:13:07 +01:00
effb4e6f40 [TWIG][CSS] Complete HTML refactoring, now using details element instead of a checkbox trick per panel. Using a "grid" akin to IBM's Carbon design guidelines. 2021-09-14 13:13:07 +01:00
3de10192ef [TWIG][CSS] Timeline WIP. Creating a notice is now done on the right panel. HTML structure improvements, such as the timeline divided from the navigation div. 2021-09-14 13:13:07 +01:00
a3f50e6732 [TWIG][CSS] Base template structural refactoring to accommodate true canons of page construction. CSS WIP to reflect these changes.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:07 +01:00
0b9cc721c4 [TWIG][CSS] Fixed right panel buttons, fix issue where the form was invalid on send.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:07 +01:00
c7a28876aa [TWIG][CSS] Right panel WIP. Create a note now looks better, need to style in some way the default user agent buttons without removing features (e.g. current file chosen).
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:07 +01:00
fc3ac1c2f4 [TWIG][CSS] Left panel profile section done.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:06 +01:00
14358b4b95 [TWIG][CSS] Register and Login styling done.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:06 +01:00
0c2272e094 [CSS] Fixing poor responsiveness to main nav element hover animation.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:06 +01:00
d45ef53efd [CSS][TWIG] Left panel HTML nesting to better aid screen readers.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:06 +01:00
1037d3397b [CSS][TWIG] Panels icons are now hidden on desktop view to stop possible inconsistencies on window resizing. Left Panel polish.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:06 +01:00
db8a1b125f [CSS][TWIG] Details element is now shown by default on larger screens, and hidden on smaller screens.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:06 +01:00
15cdcd3344 [CSS][TWIG] Timeline navigation is now a part of the left panel, this way more items could be displayed at a time. Left panel styling WIP.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:06 +01:00
701b4967b4 [TWIG] Microformats added to timeline, note's view and media. Should be backwards compatible as well.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:06 +01:00
cab7ba8e79 [CSS] Fixed accessibility issues with header and panel elements. Left, instance and right elements are now properly ordered when focused.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:06 +01:00
0620923ac6 [CSS] Fixed incorrect Chromium based browsers improper main content view. Flex item order (shouldn't be a problem, but it was) and padding for the container class was the root issue.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:05 +01:00
1c4568d064 [CSS] Main container 'order' attribute was somehow a problem in Chromium. 2021-09-14 13:13:05 +01:00
580f2d9962 [CSS] Fixed top content margin. 2021-09-14 13:13:05 +01:00
bfd0fa74f2 [TWIG][CSS] Accessibility improvements, all general links provide proper feedback now. Base theme CSS progress, page now looks more as it should. Panels WIP. 2021-09-14 13:13:05 +01:00
a44e81a1ed [TWIG][CSS][ICONS] New profile and notice creation panel, alternative text set correctly for header icons. WIP in base styling and panels. 2021-09-14 13:13:05 +01:00
f687c7b315 [TWIG][CSS] Found solution to show details content by default in desktop view. However, post_form is being rendered multiple times, it was already rendered in the Posting Component. Needs to be fixed. 2021-09-14 13:13:05 +01:00
b899c9fb2a [TWIG][CSS] Panels are now animated when shown, main content width as well as panel's is now correctly configured. WIP: displaying side panels by default when space is available, "details" element state cannot be manipulated through CSS only, need a better solution. 2021-09-14 13:13:05 +01:00
2084ae350e [TWIG][CSS] Panels functionality works as intended, size needs to be worked upon. 2021-09-14 13:13:05 +01:00
3812a2d04d [TWIG][CSS] Complete HTML refactoring, now using details element instead of a checkbox trick per panel. Using a "grid" akin to IBM's Carbon design guidelines. 2021-09-14 13:13:05 +01:00
ee3ed5f096 [TWIG][CSS] Timeline WIP. Creating a notice is now done on the right panel. HTML structure improvements, such as the timeline divided from the navigation div. 2021-09-14 13:13:05 +01:00
d3c47a2557 [TWIG][CSS] Base template structural refactoring to accommodate true canons of page construction. CSS WIP to reflect these changes.
Signed-off-by: Eliseu Amaro <mail@eliseuama.ro>
2021-09-14 13:13:04 +01:00
80cde06f4b [MEDIA][Thumbnail] Fix non-instantiated variable 2021-09-14 13:13:04 +01:00
dc3801f6ae [DOCS][Dev] Write paradigms 2021-09-14 13:13:04 +01:00
cb7fa0a081 [SECURITY] Remove aggressive normalization of nicknames. This will be moved to a plugin in the future and we'll open an RFC, as discussed 2021-09-14 13:13:04 +01:00
4ec9b910c2 [TOOLS] Fix pre commit hook to allow for partial file commits (git add -p/git reset -p) 2021-09-14 13:13:04 +01:00
a5348f2427 [MEDIA][AttachmentThumbnail] Add mimetype to Entity 2021-09-14 13:13:04 +01:00
41dcef3c7b [Media] EncoderPlugins should handle the views that concern them
Ensure the intended filetypes and mimetypes during Vips conversions (part 2)
Sanitize Attachments instead of Validate (part 2)
Various bug fixes
2021-09-14 13:13:04 +01:00
861732176e [Media] Support any kind of thumbnails in the Core
Sanitize Attachments instead of Validate (part 1)
Ensure the intended filetypes and mimetypes during Vips conversions (part 1)
Various bug fixes
2021-09-14 13:13:03 +01:00
481e953cde [Media] File quota should be triggered by the Core 2021-09-14 13:13:03 +01:00
488e700fab [POSTING] Make it possible for plugins to change the placeholder string 2021-09-14 13:13:03 +01:00
72dcff22f7 [MEDIA] We need permissions to run chmod in directories
It's better to have in the filename data that we couldnt't otherwise rapidly retrieve
2021-09-14 13:13:03 +01:00
6ecdaa5d72 [MEDIA] Fix database misses on thumbnail retrieval
We were storing the real scaling values instead of the predictions, but the core is never able to pre-compute the real values generated by the encoding plugins so, we have to rely on our own aproximation function ported from v2
2021-09-14 13:13:03 +01:00
c8cf8c3f13 [FILE][TemporaryFile] Fix various issues now that we also have Symfony's file abstractions 2021-09-14 13:13:03 +01:00
6c0f3a336e [DOCS][Developer] Adopt a top-down approach
Minor corrections to the overview
2021-09-14 13:13:03 +01:00
8817613016 [CORE][GNUsocial] Fix undefined property typo 2021-09-14 13:13:03 +01:00
6cf7693f14 [DOCS][User][SysAdmin] Add thomask as an author as we're starting this from his unofficial docs 2021-09-14 13:13:03 +01:00
d5ab382485 [DOCS] Add designer book. 2021-09-14 13:13:02 +01:00
c33a65c45e [DOCKER][nginx] Removing default nginx config through docker/nginx/domain.sh. The default config conflicts with 'localhost' server_name. 2021-09-14 13:13:02 +01:00
b42128014e [DOCS] Elaborate initial architecture page 2021-09-14 13:13:02 +01:00
9f553707ba [CORE] Proxies: constant HEADER_X_FORWARDED_ALL is deprecated
Give ENV preference over SERVER
2021-09-14 13:13:02 +01:00
687b2e2bc7 [UTIL] Add utility to flatten the result of note queries 2021-09-14 13:13:02 +01:00
74f477489b [TESTS] Raise test coverage for App\Controller\Network to 100% and fixup related code 2021-09-14 13:13:02 +01:00
c5d4b7ecac [UI] Remove margin in timeline container 2021-09-14 13:13:02 +01:00
86400ce815 [UTIL] Provide static access to current request and utilities in Common 2021-09-14 13:13:02 +01:00
9198797aea [CORE] Throw more meaningfull error when method doesn't exist in Security and Entity 2021-09-14 13:13:02 +01:00
6d93b6fb32 [TESTS] Raise App\Core\DB\DB test coverage to 100% and fix issues found 2021-09-14 13:13:01 +01:00
52edaa319b [TESTS] Raise App\Core\DB\UpdateListener test coverage to 100% 2021-09-14 13:13:01 +01:00
d49541629d [TESTS] Change relevant tests to use GNUsocialTestCase, so they can access all the needed features 2021-09-14 13:13:01 +01:00
b9fbed2e3d [CORE] Clarify message when calling non existent method in Entity 2021-09-14 13:13:01 +01:00
45f54e615c [TESTS] Merge datafixtures to allow for using the correct ID in notes, and add group_inbox 2021-09-14 13:13:01 +01:00
e1a1d01844 [TESTS] Add GNUsocialTestCase, which initializes our infrastructure when bootKernel is called 2021-09-14 13:13:01 +01:00
d31c3b1784 [AUTOGENERATED] Update autogenerated code 2021-09-14 13:13:01 +01:00
10c79bcafe [TOOLS][TESTS] Add coverage ignore tag to autogenerated code 2021-09-14 13:13:00 +01:00
de0c35d5a6 [TOOLS][TESTS] Add a data fixture with example notes, for testing 2021-09-14 13:13:00 +01:00
fbe0f36a53 [TESTS] Expand test coverage for App\Util\Forms\ArrayTransformer, App\Util\Notification and App\Twig\Runtime 2021-09-14 13:13:00 +01:00
6591d78a9c [TWIG] Remove unused Twig function 'get_note_other_content' 2021-09-14 13:13:00 +01:00
f0c6aa761b [TESTS] Add ignored files and folders to config 2021-09-14 13:13:00 +01:00
c84fcc608f [TESTS] Raise App\Util\TemporaryFile test coverage to 100% 2021-09-14 13:13:00 +01:00
ffa3774c46 [TOOLS][TESTS] Make tests run as www-data 2021-09-14 13:13:00 +01:00
fc9b934bbc [UTIL] Fix App\Util\TemporaryFile, adding default options and preventing warning on not enough permission 2021-09-14 13:12:59 +01:00
01a659e5b3 [TESTS] Raise test coverage for NicknameTest to 100% 2021-09-14 13:12:59 +01:00
31b6211bd0 [TOOLS][TESTS] Add data fixtures, which populate the database with users used for testing 2021-09-14 13:12:59 +01:00
ec1081ed43 [UTIL] Rename and rewrite isTaken to checkTaken 2021-09-14 13:12:59 +01:00
bd249b508b [ENTITY] Add 'normalized_nickname' to GSActor, the result of Nickname::normalize, so we can make sure we don't have very similar nicknames duplicated 2021-09-14 13:12:59 +01:00
f2727f9327 [DEPENDENCIES] Add doctrine/doctrine-fixtures-bundle, which allows populating the database in the testing environment 2021-09-14 13:12:59 +01:00
d2020eb7d8 [TOOLS][TESTS] Adjust configuration for testing environment 2021-09-14 13:12:59 +01:00
a49ee453ab [TESTS] Raise App\Util\HTML test coverage to 100% 2021-09-14 13:12:58 +01:00
fbea08ca9b [TESTS] Raise App\Util\Bitmap test coverage to 100% 2021-09-14 13:12:58 +01:00
abda73b8e3 [TESTS] Raise App\Util\Common test coverage to 100% 2021-09-14 13:12:58 +01:00
3fab198c04 [ENTITY] Add uniqueness constraint to Attachment::file_hash 2021-09-14 13:12:58 +01:00
4f936108a1 [ATTACHMENTS] Don't store an attachment if it's a dupplicate, reuse it 2021-09-14 13:12:58 +01:00
2b83a4b627 [UTILS][TemporaryFile] Change way TemporaryFile takes arguments and it's internal implementation 2021-09-14 13:12:58 +01:00
3b39046a38 [UTIL] Fix bugs found in App\Util\Formatting by tests 2021-09-14 13:12:58 +01:00
15a8f8ab7f [TESTS] Add tests increasing coverage of App\Util\Formatting to 100% 2021-09-14 13:12:58 +01:00
5d326bd18e [TESTS] Move testing container's DB and Redis to different ports, so it can be used at the same time as the regular containers 2021-09-14 13:12:58 +01:00
ee97cc5b00 [TESTS] Add test container with Xdebug and allow for generation of coverage reports with 'make test' 2021-09-14 13:12:57 +01:00
091f4b5194 [ATTACHMENTS] Do not create thumbnails for attachments with mimetype different from 'image|video' 2021-09-14 13:12:57 +01:00
6a999b8237 [Embed] Do not create AttachmenThumbnail 2021-09-14 13:12:57 +01:00
b6d7d46719 [ENTITY] Fix entity->has to access private properties with closure bindTo 2021-09-14 13:12:57 +01:00
da3754efba [CSS][Network] Minor fixes concerning attachment representation (centering and width) 2021-09-14 13:12:57 +01:00
1e7d8cac9a [ATTACHMENTS] Follow URL redirects and don't duplicate attachments 2021-09-14 13:12:57 +01:00
adb6680a01 [ATTACHMENTS] Respect config for smart crop 2021-09-14 13:12:57 +01:00
ab060332f0 [Posting] Don't sanitize on storage
We prefer to have the original input in database and sanitize on output when appropriate
2021-09-14 13:12:57 +01:00
8f43c8b405 [AUTOGENERATED] Update auto generated code 2021-09-14 13:12:57 +01:00
4fcccb1d1c [CORE][ImageEncoder] Add width and height back in attachment entity and allow for differently sized thumbs
The strategy adopted involves predicting the thumb size as we did in v2 before having vips resize
2021-09-14 13:12:56 +01:00
1c9f807595 [Embed] Fix some bugs and change AttachmentEmbed::url to ::media_url 2021-09-14 13:12:56 +01:00
c9090e6cee [ATTACHMENTS][GSFile] Rename ValidateAndStore functions 2021-09-14 13:12:56 +01:00
a3860e6257 [Embed] Local config 2021-09-14 13:12:56 +01:00
186e31e20d [DEPENDENCIES] Add ext-curl 2021-09-14 13:12:56 +01:00
6d31945401 [ATTACHMENTS] In sendFile, check that file exists or show a custom exception 2021-09-14 13:12:56 +01:00
38cf8f8efe [ENTITY] Change foreign key definition to new format for cover and profile_color tables 2021-09-14 13:12:56 +01:00
cfe842b487 [DOCUMENTATION] Add database diagram to developer documentation 2021-09-14 13:12:56 +01:00
06b236374d [CSS][Network] Improve attachment representation
Part of why we have thumbnails with a specific size is so that they are in the proper theme size
2021-09-14 13:12:56 +01:00
612c809469 [CSS][Left] Vertical scroll on left menu when it doesn't fit the screen 2021-09-14 13:12:55 +01:00
7a2f5e352b [CSS][Network] Fix horizontal menu on smaller screens 2021-09-14 13:12:55 +01:00
837f644458 [UTIL][Formatting] Add twigRenderFile 2021-09-14 13:12:55 +01:00
e9a96f1c9b [DOCUMENTATION] Add high level code walkthrough to developer docs 2021-09-14 13:12:55 +01:00
353595eb97 [Posting] Add missing default visibility option 2021-09-14 13:12:55 +01:00
5067bcd074 [ImageEncoder][FileQuota] Move quota enforcement to it's own plugin, so it can be easily shared and disabled 2021-09-14 13:12:55 +01:00
5bd16a509e [TEMPLATES] Fix identation 2021-09-14 13:12:55 +01:00
8cb64ede7f [AttachmentShowRelated] Move Attachment related to plugin 2021-09-14 13:12:55 +01:00
29a215534d [SECURITY] We can't really show a stream for this, was a nice concept, but not properly doable without requiring JS 2021-09-14 13:12:55 +01:00
d11615ded6 [Avatar][Embed] Change use of TemporaryFile::getPath to getRealPath 2021-09-14 13:12:55 +01:00
aad4bddedd [ImageEncoder] Implement attachment validation for images. This limits the maximum dimensions of the file, enforces a per file, per user and per user-month size quota and fixes the title if it's a filename, by replacing the extension to the new one 2021-09-14 13:12:54 +01:00
7509913fcf [ENTITY] Add field size to attachments, used for quota calculations 2021-09-14 13:12:54 +01:00
29457ef50d [UTIL] Add option for setting a file suffix on TemporaryFile constructor and add missing TemporaryFileException 2021-09-14 13:12:54 +01:00
a165e533bb [CONFIG] Add attachments/max_{width,height} config option, which is used as maximum dimensions when validating attachments 2021-09-14 13:12:54 +01:00
8ad8546aab [DEPENDENCIES] Add oroinc/doctrine-extensions, which provides cross database platform date functions 2021-09-14 13:12:54 +01:00
a0b820fd76 [CSS] Refactor Right Panel style 2021-09-14 13:12:54 +01:00
2d8d8ffb48 [TEMPLATES] Add dynamic blocks to right panel 2021-09-14 13:12:54 +01:00
4bd081ad27 [CSS] Fix invisible checkboxes 2021-09-14 13:12:54 +01:00
110c2572a4 [TEMPLATES] Minor refactoring, extending left was weird 2021-09-14 13:12:54 +01:00
e9b2b18093 [Avatar] Implement avatar deletion 2021-09-14 13:12:53 +01:00
2ec7059076 [AVATAR] Move avatar settings page to Avatar component 2021-09-14 13:12:53 +01:00
ced610d942 [Embed] Use Formatting utilities rather than substr and such 2021-09-14 13:12:53 +01:00
9008bee558 [Embed] Add docblock to handle function to pass pre-commit hook 2021-09-14 13:12:53 +01:00
88e5cec8fc [ENTITY][GSActor] Fix getAvatarUrl method 2021-09-14 13:12:53 +01:00
cbd383f92d [RIGHT] Introduce component abstraction 2021-09-14 13:12:53 +01:00
143b2460e9 [VIEWS] Minor proofreading of templates and css 2021-09-14 13:12:53 +01:00
aea8639d44 [ATTACHMENTS] Restrict thumbnail generation to allowed sizes. Defaults to only configured sizes, but can be extended with the event 'GetAllowedThumbnailSizes'. The intention is to prevent DoS attacks, since handling a thumbnail request is a relatively slow process 2021-09-14 13:12:53 +01:00
4f6f1941da [UI] Fix 'hide_attachments is not defined' error 2021-09-14 13:12:53 +01:00
436528172c [ATTACHMENTS] Add controller and templates for the attachment show page, which shows extra info about an attachment, such as related notes and tags 2021-09-14 13:12:53 +01:00
be91fb754d [CORE] Typo in GSFile and slight Twig weirdness in base template 2021-09-14 13:12:52 +01:00
b1e514832b [Embed][ENTITY] Fix embed route and use attachment_view rather than _show. Rename Entity::have to Entity::has, because grammar 2021-09-14 13:12:52 +01:00
30107de079 [Embed] Fix plugin. Only attempt to show an image, if we have one 2021-09-14 13:12:52 +01:00
2adb3c3521 [ATTACHMENTS] Add event 'AttachmentFileInfo' to allow a plugin to override the file displayed 2021-09-14 13:12:52 +01:00
708a910870 [UTIL] Fix remove affix utilities, so they only try to remove an affix if the string starts/ends with it 2021-09-14 13:12:52 +01:00
8988d89192 [CONFIG] Add attachment related parameters to default config 2021-09-14 13:12:52 +01:00
a7ef2babe6 [AUTOGENERATED] Update autogenerated code 2021-09-14 13:12:52 +01:00
ece3c11e1b [DB] Fix error in config/services.yaml where the wrong namespace was used for the UpdateListener 2021-09-14 13:12:52 +01:00
fb220e82ed [TOOLS] Use \DateTimeInterface rather than DateTimeInterface 2021-09-14 13:12:52 +01:00
bb1ba11fcf [AUTOGENERATED] Run bin/generate_entity_fields for the Embed plugin 2021-09-14 13:12:51 +01:00
4cd152f640 [Embed] Review and port v2 code 2021-09-14 13:12:51 +01:00
7adc198a52 [ENTITY] Add meta method 'have*' to Entity base class, which checks if a field 'isset' 2021-09-14 13:12:51 +01:00
34059a8d3d [ATTACHMENTS][EVENT] Add onHashFile event, which can be used to deduplicate files
Currently, we simply hash the contents of the file with sha256, but in the future we can use something smarter,
which could find visual feature similarity between images
2021-09-14 13:12:51 +01:00
60a9085e56 [FORMATTING] Add utilities to remove affixes from strings 2021-09-14 13:12:51 +01:00
b647e31495 [DEPENDENCIES] Add 'embed/embed', 'nyholm/psr7' and 'symfony/dom-crawler' 2021-09-14 13:12:51 +01:00
9a7f1358c2 [ENTITY] Add utils to Attachment and AttachmentThumbnail to get the corresponding URL and html representation parameters 2021-09-14 13:12:51 +01:00
2a74dced22 [UTIL] Add TemporaryFile class, courtesy of Alexei Sorokin from v2, a class that ensures files stored in /tmp are removed, as it doesn't happen in some cases 2021-09-14 13:12:51 +01:00
7dab063a72 [PLUGINS] Remove scripts. These will need to be implemented with Commands 2021-09-14 13:12:48 +01:00
3d8c348cb8 [Emebed] Add Embed plugin and initial cleanup 2021-09-14 13:12:24 +01:00
2d91095260 [UI] Use event 'ShowAttachment' to permit plugins like Embed to alter the representation 2021-09-14 13:12:23 +01:00
94edad43d9 [UTIL] Add method to validate url 2021-09-14 13:12:23 +01:00
5c78def973 [HTTPClient] Add utility functions for all HTTP methods 2021-09-14 13:12:23 +01:00
1b8f5b7bf0 [DB] Make DB::findOneBy throw a different exception if two values are found 2021-09-14 13:12:23 +01:00
e94df546c3 [Posting] Extract and store URLs from note content. Introduce 'AttachmentStoreNew' event 2021-09-14 13:12:23 +01:00
ae0e410986 [TESTS] Fix Nickname test 2021-09-14 13:12:23 +01:00
8dff0b1d0c [Favourite] Make twig event operate on array rather than string 2021-09-14 13:12:23 +01:00
7a90e844b7 [SECURITY][DB] Make user register 'atomic', by using a single transaction for inserting all objects, to avoid partial inserts 2021-09-14 13:12:23 +01:00
77655c1248 [TESTS] Fix wrong namespace in tests 2021-09-14 13:12:23 +01:00
aeabf64051 [PLUGIN] Change base class from Module to Plugin for all plugins 2021-09-14 13:12:23 +01:00
a66118aee7 [AVATAR] Display avatar rounded 2021-09-14 13:12:22 +01:00
3afa872cec [UI] Use thumbnail path for thumbs 2021-09-14 13:12:22 +01:00
e1995f44ce [ATTACHMENTS] Move thumbnail controller to core and cleanup 2021-09-14 13:12:22 +01:00
3a7e92ed01 [ImageEncoder] Change preferred type to always be WEBP 2021-09-14 13:12:22 +01:00
1b1b3007db [AVATAR] Display avatar as round on the default theme 2021-09-14 13:12:22 +01:00
e6c6e7afd7 [AVATAR] Fix JS cropping script and save square image, in case other themes need it 2021-09-14 13:12:22 +01:00
d2bb5bba14 [ImageEncoder] Move DB::persist call to AttachmentThumbnail 2021-09-14 13:12:22 +01:00
0c8c5a4b87 [ImageEncoder] Fix error when not providing a width and/or height 2021-09-14 13:12:22 +01:00
e385a9ac29 [ATTACHMENTS] Even more further refactoring
Introduce Encoder plugins Instead of abstract upload and thumb modules

Ported attachment routes. In v3 thumbnail depends on existing attachment
so route updated accordingly.
2021-09-14 13:12:18 +01:00
0eaccc32fe [ATTACHMENTS] Further refactoring
Some key points:
- Components and Plugins shouldn't extend Module directly
- Avatars should be fetched via GSActor ID, not by nickname as that isn't unique
- Avatar now is a separate Component
- Common file utilities are now to be placed in Core\GSFile, this will
  handle storage and trigger validation
- Some bug fixes
2021-09-14 13:11:51 +01:00
cdef6858ce [ENTITY] Cache AttachmentThumbnail query result 2021-09-14 13:11:51 +01:00
65999bd183 [Poll] Move tables from core to plugin 2021-09-14 13:11:51 +01:00
716ca063d5 [ImageThumbnail] Finish image thumbnailing functionality 2021-09-14 13:11:51 +01:00
19850b5e0d [DB] Fix bug in custom criteria format wrangling 2021-09-14 13:11:51 +01:00
e834ac2c8d [DEPENDENCIES] Add php-vips 2021-09-14 13:11:51 +01:00
1d6d20aacb [TOOLS] In pre-commit hook, only run php-doc-check if some PHP file changed 2021-09-14 13:11:51 +01:00
081b0de919 [DOCKER] Add VIPS PHP extension to Docker build 2021-09-14 13:11:51 +01:00
4358656c55 [ImageThumbnail] Implement image resizing with Intervention/Image 2021-09-14 13:11:50 +01:00
ee87961d96 [ImageThumbnail] Structure of plugin to generate thumbnails for image attachments 2021-09-14 13:11:50 +01:00
7284c833a6 [DB] Allow DQL queries with table name rather than entity 2021-09-14 13:11:50 +01:00
0d01f1d060 [CORE] Add functionality to App\Core\Controller to get and validate GET parameters 2021-09-14 13:11:50 +01:00
c053e8da8e [Posting] Rename file to attachment and cache result of actor tag query 2021-09-14 13:11:50 +01:00
5579f4fa5d [MEDIA] Rename File to Attachment 2021-09-14 13:11:50 +01:00
dc5bdfa1fb [CORE] Rename NoteScope to VisibilityScope, as it will be used for attachment visbility too 2021-09-14 13:11:50 +01:00
9659762726 [DB] Add table map which allows using table names rather than entities in Doctrine operations 2021-09-14 13:11:50 +01:00
c44443b52c [AUTOGENERATED] Update autogenerated code 2021-09-14 13:11:50 +01:00
483ac38888 [Directory] Fixup directory plugin 2021-09-14 13:11:49 +01:00
cc9f2d6ff2 [DOCUMENTATION] Three books instead of only one
The User one is intended to illustrate the various common use cases, possibilities regarding customization and introduce the existing functionalities.

The Administrator one explains the step by step of how to install and maintain a GNU social instance, be it as node of The Free Network or as an intranet social network in a company setting.

The Developer one starts by introducing the Modules system and architecture, then the plugin development process and finally the exciting internals of GNU social for those looking forward to make the most advanced contributions.
2021-09-14 13:11:49 +01:00
e7ed325ac6 [MEDIA] Refactor File as Attachment 2021-09-14 13:11:49 +01:00
566c7694b5 [CONFIG][TWIG] Move twig config to php code to add support for placing templates in modules (plugins and components) 2021-09-14 13:11:49 +01:00
a220d07b0f [Directory] Move templates from core to plugin 2021-09-14 13:11:49 +01:00
ed59cce0f9 [COMPOSER][Media] Add example composer.json in plugins/Media 2021-09-14 13:11:49 +01:00
299bc5b551 [TWIG] Add way to launch events from TWIG, capture service and add way to render from a string 2021-09-14 13:11:49 +01:00
1b7c48c732 [LEFT][EVENT] Add event allowing plugins to add links to the left panel 2021-09-14 13:11:49 +01:00
8e56dbb95c [Favourite] Move table and left panel links to plugin 2021-09-14 13:11:49 +01:00
5f4815b12f [DEPENDENCIES] Add wikimedia/composer-merge-plugin 2021-09-14 13:11:48 +01:00
1687ecaa24 [FAVOURITE] Temporary commit to fix exception in timeline 2021-09-14 13:11:48 +01:00
974bbe164e [Favourite] Move controller to plugin 2021-09-14 13:11:48 +01:00
00d71e7035 Rename FFmpeg to VideoThumbnail FIXME 2021-09-14 13:11:48 +01:00
ccf3aa990a [MODULES] Introduce the concept of abstract modules to V3
Introduce placeholder for abstract upload and thumb modules
Temporarily supress some bugs
2021-09-14 13:11:45 +01:00
539f1861a6 [NETWORK] Fix big brain bug 2021-09-14 13:10:55 +01:00
ea802621aa [ENTITY] Remove extraneous File_thumbnail.php file 2021-09-14 13:10:55 +01:00
55b06705d5 [SCRIPTS] pre-commit now has variables double quoted 2021-09-14 13:10:55 +01:00
9997b231d4 [INSTALL] Elaborate on localhost installation 2021-09-14 13:10:54 +01:00
f8199159c3 [FFmpeg] Copy FFmpeg plugin from v2 2021-09-14 13:10:54 +01:00
155f30e816 [TOOLS] Fix missing exported variable in bin/configure 2021-09-14 13:10:54 +01:00
3b901745d5 [Embed][StoreRemoteMedia][Media] Copy and cleanup plugins from v2 2021-09-14 13:10:54 +01:00
fe478c6104 [Media] Copy media subsystem from v2 and roughly structure it for v3 2021-09-14 13:10:54 +01:00
a38ee03f18 [TOOLS][DOCKER] Make sure composer doesn't require interaction when installing 2021-09-14 13:10:54 +01:00
ad67358c3b [ActivityPub] Remove ActivityPub plugin until we're ready to work on it, as it needs significant work 2021-09-14 13:10:51 +01:00
e2e561e663 [DB][FKEY] Temporarily disable foreign key mapping, as there seems to be a bug in doctrine, which is under investigation 2021-09-14 13:10:23 +01:00
faa362e2e2 [DB] Remove unique constraint from GSActor.nickname and fix register and related functionality 2021-09-14 13:10:23 +01:00
68de1b09b1 [NICKNAME] Don't throw when normalizing reserved nicknames 2021-09-14 13:10:23 +01:00
78548365da [WEB] Fix translations and small inconsistency when opening on web 2021-09-14 13:10:23 +01:00
8b5bd40421 [TESTS] Add tests to all relevant methods under App\Util and fix errors that popup 2021-09-14 13:10:23 +01:00
57dad5eca4 [NICKNAME] Add nickname min length config and check it in Nickname::normalize 2021-09-14 13:10:23 +01:00
92d0848280 [DEPENDENCIES] Add jchook/phpunit-assert-throws and update dependencies 2021-09-14 13:10:23 +01:00
5afd2c9843 Duplicate src/Util/Exception/NicknameTooLongException.php history in src/Util/Exception/NicknameTooShortException.php history. 2021-09-14 13:10:23 +01:00
dc2a453e94 [TESTS] Add tests of Common and fix small oddities that pop up 2021-09-14 13:10:22 +01:00
b387ea9aa0 [TESTS] Fix error when testing cold redis cache 2021-09-14 13:10:22 +01:00
88e4044d02 [TESTS] Add tests for the bitmap utility and fix implementation 2021-09-14 13:10:22 +01:00
8d25859de7 [LOG] Only try to log if setup, so logs can be disabled, in tests, for instance 2021-09-14 13:10:22 +01:00
7e648a296f CACHE] Fix cache implementation with the help of tests and remove premature optimization for non-redis list caching
This complicated the code significantly and likely didn't help that much, if at all. The recommended setup is using Redis, anyway, which is plenty optimized
2021-09-14 13:10:22 +01:00
c539f17ba5 [TESTS] Add App\Core\Cache test 2021-09-14 13:10:22 +01:00
121faccb22 [DEPENDENCIES] Update dependencies, including redis-polyfill, to be able to implement a test 2021-09-14 13:10:22 +01:00
eb951b49bf [TESTS] Update PHPUnit configuration and upgrade to version 9.5 2021-09-14 13:10:22 +01:00
ff771223af [DOCKER][TOOLS] Add option to bin/configure to use a prebuilt PHP container (https://hub.docker.com/repository/docker/gsocial/php) 2021-09-14 13:10:22 +01:00
c8b2a7a2e0 [TESTS] Fix deprecations 2021-09-14 13:10:21 +01:00
ec9a9cec13 [DOCKER] Fix default docker-compose file 2021-09-14 13:10:21 +01:00
1028f05cd8 [TESTS] Fix unkept unit tests 2021-09-14 13:10:21 +01:00
2d70f484f2 [TEST] Fix translation test 2021-09-14 13:10:21 +01:00
f5a6e2f047 [DEPENDENCIES] Upgrade to Symfony 5.2 to get my upstream ICU translation feature 2021-09-14 13:10:21 +01:00
3b897abddb [DOCUMENTATION] Add documentation on installing without docker and other topics 2021-09-14 13:10:21 +01:00
12347af6bc [DOCUMENTATION] Add documentation on installing with Docker 2021-09-14 13:10:21 +01:00
c66801a5c4 [DOCTRINE][CONFIGURATION] Add new required Doctrine DBAL parameter, for testing environments 2021-09-14 13:10:21 +01:00
03a0df987e [DEPENDENCIES] Update all dependencies 2021-09-14 13:10:21 +01:00
2174f288d1 [DB] Fix Doctrine errors due to lack of column uniqueness
So, Doctrine doesn't like that `GSActorTag.tag` is not unique, even
though composite key `[tagger, tag]` is. `tag` can't unique, but
doctrine doesn't understand this. This seems like a Doctrine bug that
should be investigated. For now we'll just not mark it as a foreign
key
2021-09-14 13:10:20 +01:00
2e490756b9 [DOCKER][MAIL] Temporarily disable mail container 2021-09-14 13:10:20 +01:00
1773ab7af2 [DOCKER][MAIL] Update config and change the way mail docker handles it, so the edits aren't visible from the outside, polluting the git staging area 2021-09-14 13:10:20 +01:00
b3623329e3 [DOKER][MAIL][BOOTSTRAP] Make bootstrap generate separate certificates for the web root and the mail server 2021-09-14 13:10:20 +01:00
b824a0425e [DOCKER] Remove quotes from docker env files, as docker (or at least docker-compose) include them in the actual value 2021-09-14 13:10:20 +01:00
c894a4faa4 [DB] Make Note.source reference NoteSource.code, the primary key 2021-09-14 13:10:20 +01:00
a4a1a21403 [DOCKER] Rename docker-compose.yaml, so there can still be a default one on the repo, while the previous name can be used by the configurator without having problems with git 2021-09-14 13:10:20 +01:00
0e9737ee39 [TOOLS][DOCKER] Rewrite the configuration script to use whiptail/dialog, and refactor 2021-09-14 13:10:20 +01:00
Angelo D. Moura
8a48236d2d [UI][NOTE][MARKDOWN] Add markdown support to the notes 2021-09-14 13:10:20 +01:00
up201706832
8cc0360298 [REPLY] Fixed CSS for reply form, making it now usable 2021-09-14 13:10:19 +01:00
up201706832
f9443f1e87 [AUTH][REMEMBER-ME] Changed name of column in rememberme_token database table to fix bug 2021-09-14 13:10:19 +01:00
Daniel
15454cab7f [ProfileColor] Added profile color css 2021-09-14 13:10:19 +01:00
Daniel
d17582094d [ProfileColor] Visualize profile color 2021-09-14 13:10:19 +01:00
Daniel
afae038cff [ProfileColor] Added Profile Color entity, color form and db store/load to color settings controler 2021-09-14 13:10:19 +01:00
Daniel
20a5005e1d [ProfileColor] Added plugin base, controller and settings template 2021-09-14 13:10:19 +01:00
Daniel
746bf70e7d [REVERSEFAV] Added css to make Reverse favs label in one line 2021-09-14 13:10:19 +01:00
Daniel
ec85b5b96b [REVERSEFAV] Fixed typo 2021-09-14 13:10:19 +01:00
Daniel
f04923405f [REVERSEFAV] Added reverse favorourites stream/template 2021-09-14 13:10:19 +01:00
João Brandão
5516a77b33 [UI][TIMELINES] Refactored query for public stream 2021-09-14 13:10:19 +01:00
Daniel
c36436c1a1 [UI][TIMELINES] Fix undefined main_nav_tabs in logged out view 2021-09-14 13:10:18 +01:00
Angelo D. Moura
98145f4f1a [Directory] Actors stream now includes a link to groups stream 2021-09-14 13:10:18 +01:00
Angelo D. Moura
d4c0f33be4 [Directory] Lint fix - missed a coma 2021-09-14 13:10:18 +01:00
Angelo D. Moura
77d7fcc138 [Directory] Finished implementing groups stream as a plugin 2021-09-14 13:10:18 +01:00
Angelo D. Moura
fe170ff508 [Directory] Finished implementing groups stream using Directory plugin 2021-09-14 13:10:18 +01:00
Angelo D. Moura
098fdb3361 [Directory] Changed the route so the plugin Directory doesn't take over - query is not working for some reason 2021-09-14 13:10:18 +01:00
Angelo D. Moura
eb1ef4dd0f [Directory] Added the route, controller and a blank template file - something is broken 2021-09-14 13:10:18 +01:00
Angelo D. Moura
4f85efa071 [Directory] Actors are now organized by nickname 2021-09-14 13:10:18 +01:00
Angelo D. Moura
505e60d89f [Directory] Actors are no longer related with notes, and the logged in user now shows on the stream 2021-09-14 13:10:18 +01:00
Angelo D. Moura
2d91f3d0b3 [Directory] Changed the title of the template and add a css rule for actor-bio 2021-09-14 13:10:17 +01:00
Angelo D. Moura
0c5941f515 [Directory] Almost finishied creating the /actors stream - problems with the css files 2021-09-14 13:10:17 +01:00
Angelo D. Moura
517cba3510 [Directory] Add the route, controller function, and blank template file 2021-09-14 13:10:17 +01:00
Daniel
0289888397 [Directory] Add documentation 2021-09-14 13:10:17 +01:00
Daniel
019e3d91e4 [Directory] Moved /actors stream to directory plugin 2021-09-14 13:10:17 +01:00
Daniel
6c1b1323a0 [Cover] Remove of cover form 2021-09-14 13:10:17 +01:00
Daniel
b79c8b092d [Cover] Added cover route verifications 2021-09-14 13:10:17 +01:00
Daniel
4eafcd5058 [Cover] Removed commented code 2021-09-14 13:10:17 +01:00
Daniel
fdc2bc39d0 [Cover] Input restrictions, Code cleanup 2021-09-14 13:10:17 +01:00
Daniel
4949abac9d [Cover] Added cover css, changed cover settings route name 2021-09-14 13:10:16 +01:00
Daniel
e2ce1a8070 [Cover] Added temporary css 2021-09-14 13:10:16 +01:00
Daniel
aeec9149fc [Cover] Cover route, cover now renders 2021-09-14 13:10:16 +01:00
Daniel
cf8b3b7b73 [Cover] Added TWIG vars for profile plugins 2021-09-14 13:10:16 +01:00
Daniel
1cfe64cc25 [Cover] Added Cover Entity, updated form handler
Basically the same as the avatar
2021-09-14 13:10:16 +01:00
Daniel
7739518717 [Cover] Started implementing Cover plugin: base class, route, base templates, added tabs in profile template 2021-09-14 13:10:16 +01:00
Diogo Machado
f18a2a4bb6 [STATIC ANALYSIS] Started removal process for the errors found by PHPStan 2021-09-14 13:10:16 +01:00
Pastilhas
f319ccea78 [DOCKER][MAIL] Fixed hash command
Also added permissions to start.sh
2021-09-14 13:10:16 +01:00
margarida
f3c3d80892 [TOOLS][DOCKER] Add mail setup to configure 2021-09-14 13:10:16 +01:00
margarida
c36259f7c1 [TOOLS][DOCKER] Changed script to write docker-compose.yaml 2021-09-14 13:10:15 +01:00
margarida
6cb6eeb8a3 [TOOLS][DOCKER] Change dialog method to command substitution and redirection and add way of finding git's root 2021-09-14 13:10:15 +01:00
margarida
a8d211cdbf [TOOLS][DOCKER] Added input verfication 2021-09-14 13:10:15 +01:00
margarida
152d173e69 [TOOLS][DOCKER] Added first version of configuration shell script 2021-09-14 13:10:15 +01:00
João Brandão
85666b195b [UI] Visual restructure of login/register pages 2021-09-14 13:10:15 +01:00
João Brandão
7c7a03cfe1 [UI] Show public stream on login/register pages 2021-09-14 13:10:15 +01:00
up201706832
9351039a3b [UI] Extracted public stream on login/register pages to a twig template 2021-09-14 13:10:15 +01:00
João Brandão
ac480e5018 [UI] Visual restructure of login/register pages 2021-09-14 13:10:15 +01:00
Pastilhas
5b088dabc2 [DOCKER][MAIL] Fixed variable expansion in run 2021-09-14 13:10:15 +01:00
Pastilhas
d291a8dae5 [DOCKER][MAIL] Cleanup opendkim.conf
Also improved consistency in other files
2021-09-14 13:10:14 +01:00
Pastilhas
67483e415c [DOCKER][MAIL] Removed unsued files, modified dovecot.conf 2021-09-14 13:10:14 +01:00
Pastilhas
19ed10078f [DOCKER][MAIL] User is now created on setup and Dockerfile
Continuation of previous commit
2021-09-14 13:10:14 +01:00
Pastilhas
2c3599721e [DOCKER][MAIL] Removed unused config files and scripts
Now user is created on setup and dockerfile
2021-09-14 13:10:14 +01:00
Pastilhas
0518bc2c6b [DOCKER][MAIL] Substituted supervisord for s6 2021-09-14 13:10:14 +01:00
Pastilhas
def5e06a28 [DOCKER][MAIL] Moved and modified setup.sh 2021-09-14 13:10:14 +01:00
Pastilhas
93939d8b25 [DOCKER][MAIL] Switched named volume to shared volume and changed env vars to env file 2021-09-14 13:10:14 +01:00
Pastilhas
0137a68ccb [DOCKER][MAIL] Improved exec.sh 2021-09-14 13:10:14 +01:00
Pastilhas
cea170ed18 [DOCKER][MAIL] Fixed small bug with ssl certificates 2021-09-14 13:10:14 +01:00
Pastilhas
11dbbef351 [DOCKER][MAIL] Fixed small bugs in config and scripts 2021-09-14 13:10:14 +01:00
Pastilhas
c2e6e3706f [DOCKER][MAIL] New config files 2021-09-14 13:10:13 +01:00
Pastilhas
419a2ceb1a [DOCKER][MAIL] Fused services into single container 2021-09-14 13:10:13 +01:00
Pastilhas
86a95def01 [DOCKER][MAIL] Changed directory path 2021-09-14 13:10:13 +01:00
Pastilhas
bc1d85de56 [DOCKER][MAIL] Setup docker mail server 2021-09-14 13:10:13 +01:00
Pastilhas
250235b1be [DOCKER][MAIL] Added docker mailserver setup 2021-09-14 13:10:13 +01:00
Daniel
1747e14824 [Poll] Removed/refactored unnecessary files, changed redirect to default parameters in new poll route 2021-09-14 13:10:13 +01:00
Daniel
c0d363e317 [Poll] Restructured templates, added misssing poll related css 2021-09-14 13:10:13 +01:00
Daniel
7a299162e1 [Poll] Polls now have an associated note, poll templates, start_show_styles event, started css 2021-09-14 13:10:13 +01:00
Daniel
090c593a61 [Poll] Started testing with note integration 2021-09-14 13:10:13 +01:00
Daniel
50ec306243 [Poll] Added file headers 2021-09-14 13:10:12 +01:00
Daniel
ffb4b9df23 [Poll] Added modified param for Poll/Poll response, added PollTest 2021-09-14 13:10:12 +01:00
Daniel
f34fb9c7b9 [Poll] Added variable num of options
not sure if it is the right way to do it
2021-09-14 13:10:12 +01:00
Daniel
cdbf7da8be [Poll] Added templates, response counting 2021-09-14 13:10:12 +01:00
Daniel
27a0c43f7b [Poll] Store poll response to DB 2021-09-14 13:10:12 +01:00
Daniel
3725818e4f [Poll] Added New Route, RespondPoll, Poll Response, PollResponseForm 2021-09-14 13:10:12 +01:00
Daniel
dbb55362c8 [Poll] Fixed ShowPoll route, moved Poll Entity, created NewPollForm
Entity was temporarily moved to src/Entity in order to load from DB, since it is yet no possible to do that from Plugin
2021-09-14 13:10:12 +01:00
Daniel
03f02bed4d [AUTOGENERATED][Poll] Add auto generated code for poll entity and new route 2021-09-14 13:10:12 +01:00
Daniel
5978a069e9 [Poll] Started porting Poll Plugin 2021-09-14 13:10:12 +01:00
margarida
c26ee45bf3 [TOOLS][DOCKER] Added input verfication 2021-09-14 13:10:11 +01:00
margarida
987d29a674 [TOOLS][DOCKER] Added first version of configuration shell script 2021-09-14 13:10:11 +01:00
Daniel
95f95d2dd8 [TESTS] Added unit tests 2021-09-14 13:10:08 +01:00
Angelo D. Moura
d53fef09a8 [TWIG] Moves the SVG custom function to an extension and change the test regex 2021-09-14 13:06:58 +01:00
Angelo D. Moura
d2208d15d8 [TWIG][TESTS] Update IconsExtension test 2021-09-14 13:06:58 +01:00
Angelo D. Moura
5acfda8ae5 [TWIG] Add SVG icon embed function 2021-09-14 13:06:58 +01:00
Diogo Machado
fbc85086fd [DB][TESTS] Implement Doctrine event listener to update timestamps on modification, and related tests 2021-09-14 13:06:58 +01:00
Daniel
c3aa2ae400 [FORM] Implement ActorArrayTransformer 2021-09-14 13:06:57 +01:00
279cfcd058 [PLUGIN][Favourite] Move favourite table definition to inside the plugin, as it is now supported 2021-09-14 13:06:57 +01:00
417e2f351b [SchemaDef] Finish association mapping implementation 2021-09-14 13:06:57 +01:00
1d42c7a835 [DB][NoteLocation] Add missing multiplicity to column 2021-09-14 13:06:57 +01:00
4e4d4dfdc5 [DB] Fix typo in table definitions and fix name of GSActorCircle table 2021-09-14 13:06:57 +01:00
481027b09b [AUTOGENERATED][DB][File][GroupJoinQueue] Update autogenerated code and add select fields as specified in the previous commit 2021-09-14 13:06:57 +01:00
1712782cc5 [DB] Change foreign key specification to new format 2021-09-14 13:06:57 +01:00
ea0aca4b00 [SCHEMADEF] Add preliminary support for foreign keys 2021-09-14 13:06:57 +01:00
9cd5560081 [DOCKER] Bump to PHP version 8 2021-09-14 13:06:57 +01:00
e2e53d9a2a [AUTOGENERATED] Update auto generated code in entities 2021-09-14 13:06:56 +01:00
b27bda6a7c [TOOLS] Use GSActor rather than Gsactor in autogenerated code 2021-09-14 13:06:56 +01:00
460712e15e [GIT] Change my email to the new one in all files and bump copyright year 2021-09-14 13:06:56 +01:00
f95f69c778 Add some missing documentation to ActivityPub 2021-09-14 13:06:56 +01:00
74e586182d [DB] Merge definition of SchemaDefDriver with SchemaDefPass for clarity 2021-09-14 13:06:56 +01:00
fc015c6fdf [NETWORK][TreeNotes] Add TreeNotes plugin which takes over the responsibility of displaying a conversation as a tree, in order to reduce the number of queries 2021-09-14 13:06:56 +01:00
5c53889739 [Reply] Fix bug where wrong variable is used when replying to a note 2021-09-14 13:06:56 +01:00
Hugo Sales
ce3cae0ef7 [DEPENDENCIES] Update all dependencies 2021-09-14 13:06:56 +01:00
Hugo Sales
eefdf74658 Ensure group table name is quoted, as it's a reserved word in postgreSQL 2021-09-14 13:06:56 +01:00
Hugo Sales
ab252accb2 Small update to php dockerfile 2021-09-14 13:06:56 +01:00
Hugo Sales
411884bfc5 [DEPENDENCIES] Update dependencies 2021-09-14 13:06:55 +01:00
1b946586e1 [DOCUMENTATION] Add mdBook stub 2021-09-14 13:06:55 +01:00
Hugo Sales
ebfd41ba0d [CONFIGURATION] Remove the individual language settings from social.yaml, as these are not something that changes at runtime 2021-09-14 13:06:55 +01:00
Hugo Sales
3301770642 [COMMAND] Change the way ListEventsCommand outputs the results to use the output interface and add some formatting 2021-09-14 13:06:55 +01:00
Hugo Sales
e8feb2ae84 [DOCUMENTATION][REFACTOR] Add documentation to all flagged function and do some small cleanup 2021-09-14 13:06:55 +01:00
Hugo Sales
67d4702743 [HOOKS] Update pre-commit script to check for missing documentation in functions 2021-09-14 13:06:55 +01:00
Hugo Sales
de8fa87079 [DEPENDENCIES] Update dependencies 2021-09-14 13:06:55 +01:00
Hugo Sales
8ce1c1cee6 [DEPENDENCIES] Update dependencies 2021-09-14 13:06:55 +01:00
Hugo Sales
1949e0b987 [EVENT] Rename event names to camel case to make finding handlers easier 2021-09-14 13:06:55 +01:00
Hugo Sales
0b759da780 [REGISTER] Add self follow when registering, fixing the '-1 followers' bug 2021-09-14 13:06:54 +01:00
Hugo Sales
089c710711 [SETTINGS][NOTIFICATIONS] Fix error when displaying the user notification settings page 2021-09-14 13:06:54 +01:00
Hugo Sales
221829c6fd [Reply] Fix missing use statement 2021-09-14 13:06:54 +01:00
Hugo Sales
be324bb390 [CONTROLLER] Fix use of undefined variable 2021-09-14 13:06:54 +01:00
Hugo Sales
74350becc5 [POSTING] Fix missing use statement 2021-09-14 13:06:54 +01:00
Tiago Magalhaes
61ebeca706 [CORE] made configure script explicitly fail when bootstrap.env is not present 2021-09-14 13:06:54 +01:00
Hugo Sales
44f51ce715 [CONFIG][CACHE] Move cache configuration from environment variables to the configuration file 2021-09-14 13:06:54 +01:00
Hugo Sales
6cf30f3f65 [UI] Make configured instance name show in UI, fix repeat icon 2021-09-14 13:06:54 +01:00
Hugo Sales
e949dd654a [CONFIG] Various fixes to use new configuration format 2021-09-14 13:06:54 +01:00
Hugo Sales
c4c693b283 [CONFIG] Fix error on missing or empty local configuration 2021-09-14 13:06:53 +01:00
Hugo Sales
dd40255c4a [CONFIG][DB] Remove config from the database, put it in yaml, so it can be baked into the container 2021-09-14 13:06:53 +01:00
Hugo Sales
d1ea9d2fdf [DEPENDENCIES] Update dependencies 2021-09-14 13:06:53 +01:00
Hugo Sales
ebb33cd6f7 [CSS][UI] Update CSS to fix reply note action (icon swap needed) and remove duplication 2021-09-14 13:06:53 +01:00
Hugo Sales
46f1cf9529 [CORE] Add missing use statement in module base class 2021-09-14 13:06:53 +01:00
Hugo Sales
179d7f3335 [UTILS] Make bitmap not use a static class var and set object properties as lowercase 2021-09-14 13:06:53 +01:00
Hugo Sales
147ff89e74 [NoteAction] Refactor duplicated code out to base class 2021-09-14 13:06:53 +01:00
Hugo Sales
a6c24393b5 [NOTE] Add isVisibleTo 2021-09-14 13:06:53 +01:00
Hugo Sales
0c0b00da93 [Directory] Add missing use statement 2021-09-14 13:06:53 +01:00
Hugo Sales
29082f4aa9 POSTING remove REPLY route 2021-09-14 13:06:52 +01:00
Hugo Sales
63d2d58e9e [EXCEPTION] Make findOne return NotFoundException 2021-09-14 13:06:52 +01:00
Hugo Sales
c07a0cdcd5 [EXCEPTION] Add base class to invalid form exception and add URL arguments to redirect exception 2021-09-14 13:06:52 +01:00
Hugo Sales
0e332b718e [SECURITY] Fix getRoles 2021-09-14 13:06:52 +01:00
Hugo Sales
c0ce25c352 [MODULES] Fix module manager dev-mode rebuild 2021-09-14 13:06:52 +01:00
Hugo Sales
0a56061639 [UI] Only show note action buttons if a user is logged in 2021-09-14 13:06:52 +01:00
Hugo Sales
2164f21834 [Controller] Fix exception handler to recurse on the exception's previous (in some contexts, RedirectException gets wrapped) 2021-09-14 13:06:52 +01:00
Hugo Sales
ffcf909bda [UTIL] Update bitmap base class, making using easier 2021-09-14 13:06:52 +01:00
Hugo Sales
a248f23cef [Reply] Move reply functionality to a plugin 2021-09-14 13:06:52 +01:00
Hugo Sales
72208b066c [NoteActions] Refactor note actions and fix bug in favourite 2021-09-14 13:06:51 +01:00
Hugo Sales
4c15271d36 [UI] Display error when submitted form is invalid 2021-09-14 13:06:51 +01:00
Hugo Sales
5fc7647c40 [MODULE][DB] Added support for loading entity definitions from modules 2021-09-14 13:06:51 +01:00
Hugo Sales
7de1654f9a FIXUP WITH DOCTRINE DEV 2021-09-14 13:06:51 +01:00
Hugo Sales
41f90f07b1 [Bridge] Replace zero dates with CURRENT_TIMESTAMP 2021-09-14 13:06:51 +01:00
Hugo Sales
6a2a0d4e66 [TOOLS] Add support for updating autocode in modules 2021-09-14 13:06:51 +01:00
Hugo Sales
cc758f6a8e [AUTOGENERATED] Update autogenerated code in module entities 2021-09-14 13:06:51 +01:00
Hugo Sales
a9b6bc78a6 [CONFIG][DEV][DOCTRINE] Add doctrine stacktrace tracking in dev mode 2021-09-14 13:06:51 +01:00
Hugo Sales
b906dde059 [EXCEPTION][UI][UX] Add RedirectException, which can be thrown anywhere to redirect somewhere, and an exception handler 2021-09-14 13:06:51 +01:00
Hugo Sales
420b4767b2 [UI][NOTE] Add reply to in UI 2021-09-14 13:06:51 +01:00
Hugo Sales
9573cab4cb [Posting] Fix form name and remove unused recycle route and controller 2021-09-14 13:06:50 +01:00
Hugo Sales
9865798766 [Media] Add cache control directive to all files served 2021-09-14 13:06:50 +01:00
Hugo Sales
6b1689e1df [Repeat][Favourite] Only display action buttons if logged in (instead of forcing login) 2021-09-14 13:06:50 +01:00
Hugo Sales
7af424b64a [DB] Add rendered collumn to note table, so we can preserve microtags from other services 2021-09-14 13:06:50 +01:00
Hugo Sales
460cbbd4c9 [DB] Fix local_user table to use a numeric id, since the username is editable 2021-09-14 13:06:50 +01:00
rainydaysavings
a69c9a4f25 [TWIG] Improving view template structure 2021-09-14 13:06:50 +01:00
rainydaysavings
099c4220d2 [TWIG] Adding active rules 2021-09-14 13:06:50 +01:00
rainydaysavings
244aa4af08 [UI] CSS polish all around 2021-09-14 13:06:50 +01:00
rainydaysavings
492360ceeb [CONTROLLER][ROUTE] Favourites page initial query implementation and routing 2021-09-14 13:06:50 +01:00
rainydaysavings
651ec890d6 [UI] Fixing Login CSS issues 2021-09-14 13:06:49 +01:00
Hugo Sales
55466143f2 [UI][FEED] Fix scope in timelines; major rewrite of home timeline query, still missing scoping and paging 2021-09-14 13:06:49 +01:00
Hugo Sales
e1181ab998 [DB][DEFAULTS] Change attachment storage location from uploads to attachments 2021-09-14 13:06:49 +01:00
Hugo Sales
3b86a46625 [DB] Rename notice to activity in notification table 2021-09-14 13:06:49 +01:00
Hugo Sales
51a398f27a [UI] Subtract self follow from total user follows 2021-09-14 13:06:49 +01:00
Hugo Sales
6e11143b79 [DB][NOTE] Update scope 2021-09-14 13:06:49 +01:00
Hugo Sales
6165f7cd55 [Media] Display images and videos inline in notes 2021-09-14 13:06:49 +01:00
rainydaysavings
a9d5f8ac5b [UI][TWIG] Fixing note actions placement and size, more descriptive rules 2021-09-14 13:06:49 +01:00
Hugo Sales
26f01c4c92 [Posting] Fix posting form name and css 2021-09-14 13:06:49 +01:00
Hugo Sales
07078414bb [FORM] Add names to forms 2021-09-14 13:06:48 +01:00
Hugo Sales
adc843c1d6 [DB] Add Activity table, to store all known activity 2021-09-14 13:06:48 +01:00
Hugo Sales
d95c22cb3e [EXCEPTION] Fix exceptions not being translated 2021-09-14 13:06:48 +01:00
Hugo Sales
80cefca90d [DB] Add wrapper for making native queries 2021-09-14 13:06:48 +01:00
Hugo Sales
a98af6ab6a [Directory] Add directory plugin, for listing people and groups 2021-09-14 13:06:48 +01:00
Hugo Sales
6dbd239544 [Posting] Add missing includes 2021-09-14 13:06:48 +01:00
rainydaysavings
7cb13ee5e9 [UI] All radio buttons now look like they should 2021-09-14 13:06:48 +01:00
rainydaysavings
ff9b5d9c01 [PLUGIN] Removing unnecessary labels 2021-09-14 13:06:48 +01:00
rainydaysavings
0649095e88 [TWIG] Making notes view more easily customizable 2021-09-14 13:06:48 +01:00
rainydaysavings
a7744351dd [UI] Fixing note actions views 2021-09-14 13:06:47 +01:00
rainydaysavings
6188524586 [PLUGIN] Recycle initial implementation 2021-09-14 13:06:47 +01:00
rainydaysavings
8a0418d8cf [Favourite] Add backend support for favourite 2021-09-14 13:06:47 +01:00
rainydaysavings
b6fb0255da [DB] Temporarily add favourite entity in core, as plugins don't support them yet 2021-09-14 13:06:47 +01:00
Hugo Sales
5b7fcc44cf [DB] Add helper for removing entities 2021-09-14 13:06:47 +01:00
Hugo Sales
ea4f2c522b [DB] Add support for calling methods with FQCN 2021-09-14 13:06:47 +01:00
rainydaysavings
4328a11eb1 [TWIG] Various routes added 2021-09-14 13:06:47 +01:00
rainydaysavings
3d3db96312 [UI] Replies border fix and other minor fixes 2021-09-14 13:06:47 +01:00
rainydaysavings
413247d344 [CONTROLLER] Replies and network queries implemented 2021-09-14 13:06:47 +01:00
rainydaysavings
a804c5f981 [COMPONENT][CONTROLLER][TWIG] Recycle component work 2021-09-14 13:06:47 +01:00
rainydaysavings
55e468bd70 [TWIG][UI] Replies CSS fixes 2021-09-14 13:06:46 +01:00
rainydaysavings
62e76cb036 [ROUTE] Network and replies routes added 2021-09-14 13:06:46 +01:00
rainydaysavings
e1e3e2d9b3 [COMPONENT] Favourite initial implementation 2021-09-14 13:06:46 +01:00
rainydaysavings
fee81f8499 [UI] Fixing note actions placement 2021-09-14 13:06:46 +01:00
rainydaysavings
0b3543aaff [UI] Responsiveness overall polish 2021-09-14 13:06:46 +01:00
rainydaysavings
baac5ef19c [UI] Browser compatibility improvements, various small fixes 2021-09-14 13:06:46 +01:00
rainydaysavings
59da3df28c [UI] Checkboxes now display a custom tick 2021-09-14 13:06:46 +01:00
rainydaysavings
189da22204 [TWIG] Timeline attachment form restructure 2021-09-14 13:06:46 +01:00
rainydaysavings
04f43a9d37 [Controller] Attempting to fix home timeline query 2021-09-14 13:06:46 +01:00
rainydaysavings
ecdd393c8e [UI] No focus outlines by default 2021-09-14 13:06:45 +01:00
rainydaysavings
47901e7ed6 [UI] Reply icon now shows accordingly, same for the replies themselves 2021-09-14 13:06:45 +01:00
rainydaysavings
1742bce78e [UI] Custom and accessible checkboxes, radio buttons and normal buttons 2021-09-14 13:06:45 +01:00
rainydaysavings
f1a687b057 [COMPONENT] Fixing typo 2021-09-14 13:06:45 +01:00
Hugo Sales
0b50905ac8 [NOTE][UI] Add note replying and UI displaying 2021-09-14 13:06:45 +01:00
Hugo Sales
459f0bf41f [CACHE] Fix bug in list caching 2021-09-14 13:06:45 +01:00
Hugo Sales
496dec4254 [MODULE] Fix avatars not loading 2021-09-14 13:06:45 +01:00
Hugo Sales
f60bdaa2f0 [DB][MODULES][ActivityPub] Cleanup table definitions 2021-09-14 13:06:45 +01:00
rainydaysavings
522f40ca2f [TWIG] Timeline template rework 2021-09-14 13:06:45 +01:00
rainydaysavings
7bc62868f7 [ROUTE] Home timeline route url now shows accordingly as the user nickname 2021-09-14 13:06:44 +01:00
rainydaysavings
e812dba033 [UI] Posting form re-styling 2021-09-14 13:06:44 +01:00
rainydaysavings
ecfda08d37 [CONTROLLER] Reply initial implementation 2021-09-14 13:06:44 +01:00
rainydaysavings
bc66e2c2a2 [COMPONENT] Posting form restructure and minor fixes 2021-09-14 13:06:44 +01:00
rainydaysavings
a8e43a4867 [TWIG] Timeline structure rework 2021-09-14 13:06:44 +01:00
rainydaysavings
7fab19fd8f [ROUTE] Home timeline added 2021-09-14 13:06:44 +01:00
rainydaysavings
d08757d0a4 [CONTROLLER] Home timeline controller work 2021-09-14 13:06:44 +01:00
rainydaysavings
9e3eb9992f [UI] Posting form styling work 2021-09-14 13:06:44 +01:00
rainydaysavings
1eab561b40 [COMPONENT] Posting form now shows a random default string 2021-09-14 13:06:44 +01:00
rainydaysavings
315a70ba0d [UI] Links removed since they are part of a plugin 2021-09-14 13:06:44 +01:00
rainydaysavings
9fcd18f751 [UI] Post form new structure first styling implementation 2021-09-14 13:06:43 +01:00
rainydaysavings
8a5cadf8d2 [UI] Small border fix 2021-09-14 13:06:43 +01:00
rainydaysavings
9b421e0095 [COMPONENTS] Small fix 2021-09-14 13:06:43 +01:00
rainydaysavings
160e56c61e [UI][TWIG] Better, divided form rendring of the posting form 2021-09-14 13:06:43 +01:00
rainydaysavings
c837194af2 [UI] Small border radius problem fix 2021-09-14 13:06:43 +01:00
rainydaysavings
1563ebc546 [COMPONENT] Posts scope initial form 2021-09-14 13:06:43 +01:00
rainydaysavings
fe0af2caed [UI] Fixing login and register styling, refactoring 2021-09-14 13:06:43 +01:00
rainydaysavings
99ac4dc2a3 [UI] Fixing issue where notices wouldn't break text 2021-09-14 13:06:43 +01:00
rainydaysavings
396af498a2 [UI] Fixing static pages styling 2021-09-14 13:06:43 +01:00
rainydaysavings
a85b5b44f1 [UI] Fixes to settings CSS 2021-09-14 13:06:42 +01:00
rainydaysavings
2c59dcefcf [UI] Finalizing timeline structure and CSS 2021-09-14 13:06:42 +01:00
rainydaysavings
33832297bd [UI] New reset CSS to deal with firefox's abysmal and evil defaults 2021-09-14 13:06:42 +01:00
Hugo Sales
b624359b9a [ActivityPub] Initial cleanup, removing 'die' statements, and ignoring the subfolders 2021-09-14 13:06:39 +01:00
Hugo Sales
38cfec8593 [UI][TWIG] Small UI cleanup and change twig 'active' function to check for starts with, rather than equals 2021-09-14 13:05:58 +01:00
Hugo Sales
f2ab77c3a9 [DB][MEDIA] Small database structure changes 2021-09-14 13:05:58 +01:00
Hugo Sales
4507b12976 [MEDIA] Only try to get an avatar if a user is logged in 2021-09-14 13:05:58 +01:00
Hugo Sales
6ed89c77f4 [UI][NOTE] Post and see attachments 2021-09-14 13:05:57 +01:00
Hugo Sales
a5cf89674e [DEPENDENCY] Add tgalopin/html-sanitizer-bundle and transitively tgalopin/html-sanitizer 2021-09-14 13:05:57 +01:00
Hugo Sales
9649bec01e [MEDIA][CACHE] Cache avatar queries and delete stale values; small refactoring 2021-09-14 13:05:57 +01:00
Hugo Sales
e3c5d7e5dc [UI][MEDIA] Add actor avatar in feed timeline 2021-09-14 13:05:57 +01:00
Hugo Sales
de22f18abf [SECURITY] Fix error in user registering where password wasn't hashed 2021-09-14 13:05:57 +01:00
rainydaysavings
1b350d51fc [UI] Fixing timeline notice structure and CSS 2021-09-14 13:05:57 +01:00
rainydaysavings
3def39fed3 [UI] Fix left panel new dynamic components view 2021-09-14 13:05:57 +01:00
Hugo Sales
09a2541c36 [UI][SELFTAGS] Display 'none' if the user doesn't have selftags 2021-09-14 13:05:57 +01:00
Hugo Sales
2486eb1949 [UI][ACCOUNT][SETTINGS] Hack to fix error related to phone number, until a solution is found upstream 2021-09-14 13:05:57 +01:00
Hugo Sales
b19be6be52 [UI][LEFT] Add # before selftags, and link 2021-09-14 13:05:56 +01:00
Hugo Sales
7e4138399c [UI][FAQ] Fix static pages 2021-09-14 13:05:56 +01:00
Hugo Sales
9159fe8d05 [CONTROLLER] Stop propagation of kernel.controller so notices aren't posted 5 times. Not sure why it happens otherwise 2021-09-14 13:05:56 +01:00
Hugo Sales
6f01b0cebe [WRAPPER][HTTPClient] Static wrapper around Symfony's HTTP Client 2021-09-14 13:05:56 +01:00
Hugo Sales
be83d3532e [DB][FOLLOW] Change Follow table 2021-09-14 13:05:56 +01:00
Hugo Sales
65a129aac6 [UI][CACHE][DB] Add follow counts to left panel, caching the results; change follow table 2021-09-14 13:05:56 +01:00
Hugo Sales
3c67773e59 [UI][LEFT] Add link to settings on avatar and personal info 2021-09-14 13:05:56 +01:00
Hugo Sales
c8e8f1f057 [ENTITY] Add Entity base class to all entities 2021-09-14 13:05:56 +01:00
Hugo Sales
d548dc9284 [MODULE][Left][UI][TAGS] Add Left module which handles fetching tags and followers, fix self tags 2021-09-14 13:05:56 +01:00
Hugo Sales
31ccb2d07b [DB][File] Remove timestamp, add actor_id 2021-09-14 13:05:55 +01:00
Hugo Sales
2e9c340684 [DB][AVATAR] Remove extraneous slash 2021-09-14 13:05:55 +01:00
Hugo Sales
44d4aade95 [DB][DEFAULTS] Add avatar/default 2021-09-14 13:05:55 +01:00
Hugo Sales
7f1ce816ae [UserPanel] Fix upload of avatar 2021-09-14 13:05:55 +01:00
Hugo Sales
f255d29078 [Media] Use utils 2021-09-14 13:05:55 +01:00
Hugo Sales
8cfa883c1b [DB] Add 'dql' method to wrap 'createQuery' and replace 'Gsactor' with 'GSActor' 2021-09-14 13:05:55 +01:00
Hugo Sales
688ee18411 [Media] Move code from media.php to utils.php 2021-09-14 13:05:55 +01:00
Hugo Sales
72876fe8dc [MODULE][Posting] Add Posting module, which handles notice posting 2021-09-14 13:05:55 +01:00
Hugo Sales
e1002eb605 [MEDIA] Move avatar fetching and adding to ouput to media component 2021-09-14 13:05:55 +01:00
Hugo Sales
8506a0248d [UTIL][Common] Fix import 2021-09-14 13:05:54 +01:00
Hugo Sales
22d1c55faf [CONTROLLER][AdminPanel] Add missing use statement 2021-09-14 13:05:54 +01:00
Hugo Sales
eb138ebdae [STREAM][NetworkPublic] Add skeleton of public timeline and posting 2021-09-14 13:05:54 +01:00
Hugo Sales
a2269f5745 [UTIL][Common] Implement 'isSystemPath' 2021-09-14 13:05:54 +01:00
Hugo Sales
95a1938d0f [SECURITY] Wrap getUser in a try catch, in case the user doesn't exist 2021-09-14 13:05:54 +01:00
Hugo Sales
213cfe5285 [COMMAND] Fix 'bin/console doctrine:database:create' by only loading defaults if we have a connection 2021-09-14 13:05:54 +01:00
Hugo Sales
e3e9ece614 [DEPENDENCY] Update dependencies 2021-09-14 13:05:54 +01:00
Hugo Sales
51a1a1180e [AUTOGENERATED] Update autogenerated code 2021-09-14 13:05:54 +01:00
Hugo Sales
636f564672 [TOOLS] Fix bin/generate_entity_fields 2021-09-14 13:05:54 +01:00
Hugo Sales
8716d700a6 [CORE][DB] Fix uses of db tables after previous restructure 2021-09-14 13:05:53 +01:00
Hugo Sales
1111ee95f1 [CORE] Data Representation and Modelling refactor 2021-09-14 13:05:53 +01:00
rainydaysavings
b80479dc4e [UI] Public feed responsive CSS work 2021-09-14 13:05:53 +01:00
rainydaysavings
5d859b6459 [UI] Responsive settings CSS work 2021-09-14 13:05:53 +01:00
rainydaysavings
ea61109932 [UI] Responsive base design polish 2021-09-14 13:05:53 +01:00
rainydaysavings
ccd6667e2c [UI] Feed structure done, feed CSS work 2021-09-14 13:05:53 +01:00
rainydaysavings
5f0ece177b [UI] Polishing design, settings pages 2021-09-14 13:05:53 +01:00
rainydaysavings
46eaccb4b0 [UI] Polishing base template 2021-09-14 13:05:53 +01:00
rainydaysavings
e9a0528275 [UI] Left panel theme now looks like it should 2021-09-14 13:05:53 +01:00
rainydaysavings
8fe12f48b5 [UI] Right panel checkbox size fix 2021-09-14 13:05:52 +01:00
rainydaysavings
80d92e3c88 [UI] Settings theme according to base theme 2021-09-14 13:05:52 +01:00
rainydaysavings
915f1dfcdb [UI] Complete base CSS overhaul and new theme 2021-09-14 13:05:52 +01:00
rainydaysavings
565140adcf [UI] Right panel added 2021-09-14 13:05:52 +01:00
rainydaysavings
1c7ea95b1f [UI] Additional fixes to settings page 2021-09-14 13:05:52 +01:00
rainydaysavings
13700edb3e [UI] Small general settings CSS fixes 2021-09-14 13:05:52 +01:00
rainydaysavings
fb0f3b9dfb [UI] Settings small fix 2021-09-14 13:05:52 +01:00
rainydaysavings
f0558feb98 [UI] Notification settings checkbox placement fix 2021-09-14 13:05:52 +01:00
Hugo Sales
9781d43f08 [LocalUser] Fix missing extend 2021-09-14 13:05:52 +01:00
Hugo Sales
cd89cf04ff [ROUTES] Add redirect from root to main/all, link from header to root, and change parameter order on RouteLoader::connect 2021-09-14 13:05:52 +01:00
Hugo Sales
365168d03e [EXCEPTION] Add ServerException and inherit previous throwable
imported from v2/5ea5d3007563f76a77efbfb66936315441922542
2021-09-14 13:05:51 +01:00
Alexei Sorokin
eb12ac5ef1 [DATABASE] Enable fulltext search by default
Also rename fulltext indices to more fitting names

Imported from v2/f84dbb369f01a1d4a9bc362d01cdd100cdc79313
2021-09-14 13:05:51 +01:00
Hugo Sales
4128a5403d [MEDIA][EXCEPTIONS] Fix errors and deprecations 2021-09-14 13:05:51 +01:00
Hugo Sales
08e5b313ce [SECURITY] Refactor 2021-09-14 13:05:51 +01:00
Hugo Sales
6438092d86 [AVATAR] Update way avatar is sent, to use proper symfony responses, make config('site', 's_static_delivery') into a boolean 2021-09-14 13:05:51 +01:00
Hugo Sales
699f25a397 [AUTOGENERATED] Update autogenerated code 2021-09-14 13:05:51 +01:00
Hugo Sales
689a5df670 [TOOLS] Update generate_entity_fields 2021-09-14 13:05:51 +01:00
Hugo Sales
bd8f4bd277 [AVATAR] Fixed avatar upload, added avatar inline download and updated template and base controller 2021-09-14 13:05:51 +01:00
Hugo Sales
2bf914f96f [AVATAR] Handle avatar upload without js and save and validate uploaded files 2021-09-14 13:05:51 +01:00
Hugo Sales
48971b70a0 [AUTOGENERATED] Update autogenerated code 2021-09-14 13:05:50 +01:00
Hugo Sales
9c660f39ed [DEPENDENCIES] Update dependencies 2021-09-14 13:05:50 +01:00
Hugo Sales
0cddbc1783 [JS] Whitespace cleanup 2021-09-14 13:05:50 +01:00
Hugo Sales
113c250c41 [MEDIA][AVATAR] Handle avatar validation and storage 2021-09-14 13:05:50 +01:00
Hugo Sales
0ab6c2ef54 [DB] Add entity base class to allow sharing methods such as 'create' 2021-09-14 13:05:50 +01:00
Hugo Sales
4d99bfb9fd [DB][FILE][AVATAR] Handle deleting files, change file and avatar tables 2021-09-14 13:05:50 +01:00
Hugo Sales
5a68fd287b [UI][SETTINGS] User notification settings with configurable transports (through plugins) 2021-09-14 13:05:50 +01:00
Hugo Sales
0230dd04df [PLUGIN] Remove Test plugin 2021-09-14 13:05:50 +01:00
Hugo Sales
86b9f7d7a1 [COMPONENT][PLUGIN] Move Email and XMPP notification handlers from components to plugins, so they can be disabled 2021-09-14 13:05:50 +01:00
Hugo Sales
3fb45176b8 [COMPONENT] Remove 'post on status change' option for email transport 2021-09-14 13:05:49 +01:00
Hugo Sales
c7dbae8067 [AUTOGENERATED] Update autogenerated code 2021-09-14 13:05:49 +01:00
rainydaysavings
db8e783233 [UI] Notifications settings styling finished 2021-09-14 13:05:49 +01:00
rainydaysavings
6b85d38ad6 [UI] Notification settings styling progress 2021-09-14 13:05:49 +01:00
rainydaysavings
bdae49718f [UI] Notification settings tabs functional 2021-09-14 13:05:49 +01:00
rainydaysavings
884d2529d3 [UI] Notifications settings page CSS work 2021-09-14 13:05:49 +01:00
rainydaysavings
ea33243b60 [UI] Accessibility improvements all around 2021-09-14 13:05:49 +01:00
rainydaysavings
54bade96ad [UI] Fixed issue where certain form element would be on top the left panel 2021-09-14 13:05:49 +01:00
rainydaysavings
d9b48d33b6 [ROUTES] Fix use statement 2021-09-14 13:05:49 +01:00
rainydaysavings
d717aac67f [JS][UI][AVATAR] JS cropping script 2021-09-14 13:05:48 +01:00
rainydaysavings
774383a3c1 [UI] Cropping avatar as a circle, proper preview done 2021-09-14 13:05:48 +01:00
rainydaysavings
574fb38225 [CONTROLLER][UI] Avatar JS cropping added 2021-09-14 13:05:48 +01:00
rainydaysavings
1d5a1818c1 [UI] Login and Register button fixes 2021-09-14 13:05:48 +01:00
rainydaysavings
f840d4350f [UI] Controller and Route for FAQ page created as well as basic template structure 2021-09-14 13:05:48 +01:00
rainydaysavings
9899601777 [UI] Settings pages routes and styling done. 2021-09-14 13:05:48 +01:00
Hugo Sales
e5082657b7 [COMPONENT][PLUGIN] Small refactor and add license 2021-09-14 13:05:48 +01:00
Hugo Sales
b436a0641d [CONTROLLER][UI] Add notification settings form 2021-09-14 13:05:48 +01:00
Hugo Sales
4ba71426b6 [MODULE] Reload modules if modified, except in production environment 2021-09-14 13:05:48 +01:00
Hugo Sales
58b6026607 [UTIL] Fix and rename arrayRemoveKeys 2021-09-14 13:05:47 +01:00
Hugo Sales
ef1788949c [CONFIG] Cleanup services.yaml config file 2021-09-14 13:05:47 +01:00
Hugo Sales
b3d5c73ab4 [FORMATTING] Update license header in SchemaDef compiler pass 2021-09-14 13:05:47 +01:00
Hugo Sales
62e093c650 [EVENT][ROUTES] Add event to allow modules to add routes, 'add_route' 2021-09-14 13:05:47 +01:00
Hugo Sales
152828ed68 [FRAMEWORK] Avoid double initializing the framework 2021-09-14 13:05:47 +01:00
Hugo Sales
aac653d2bd [EVENT] Fix event handler and rename events to snake_case 2021-09-14 13:05:47 +01:00
Hugo Sales
995b4cfb9b [PLUGIN] Update example plugin 2021-09-14 13:05:47 +01:00
Hugo Sales
ea7d43172a [MODULE][COMPILER] Add compiler pass responsible for loading, instantiating and wiring enabled modules 2021-09-14 13:05:47 +01:00
Hugo Sales
bc9de1c0fa [MODULE] Added module base class 2021-09-14 13:05:47 +01:00
Hugo Sales
b71eded942 [COMMAND] Fix ListEvents command to properly display the callable 2021-09-14 13:05:47 +01:00
Hugo Sales
292c9dc862 [COMPOSER][MODULE] Add autoloading rules for components and plugins 2021-09-14 13:05:46 +01:00
Hugo Sales
da0d88e0f2 [MODULE] Renamed modules to components 2021-09-14 13:05:46 +01:00
Hugo Sales
48252d6b8c [UTIL][FORM] Add form transformer array <--> string 2021-09-14 13:05:46 +01:00
Hugo Sales
3e6eb114c4 [UTIL] Add Common::array_remove_keys 2021-09-14 13:05:46 +01:00
Hugo Sales
fe3a3978af [UI][CONTROLLER] Work on tabbed notification settings panel 2021-09-14 13:05:46 +01:00
Hugo Sales
04e31d273d [MAIL] Make mailserver a required service 2021-09-14 13:05:46 +01:00
Hugo Sales
71db1870db [SECURITY] Ensure ARGON2 constants are defined, or throw exception 2021-09-14 13:05:46 +01:00
Hugo Sales
7560db4d5f [DEPENDENCY] Update dependencies 2021-09-14 13:05:46 +01:00
Hugo Sales
fe394e9b20 [UI][CONTROLLER] Refactor UserPanel to use the new Form::handle method and add placeholders in the password fields 2021-09-14 13:05:46 +01:00
Hugo Sales
6fc120571d [DATABASE] Remove DATABASE::flush from Profile::setSelfTags 2021-09-14 13:05:45 +01:00
Hugo Sales
b3bce3efa1 [FORMATTING] Add option to split a string to array by both a comma and a space 2021-09-14 13:05:45 +01:00
Hugo Sales
921da28884 [FORM] Add DataTransformer to and from array 2021-09-14 13:05:45 +01:00
Hugo Sales
93f576679c [FORM] Add Form::handle which automagically creates a form, handles a request, and writes the data to the given entity and update Form::create to do some more magic as well 2021-09-14 13:05:45 +01:00
Hugo Sales
59eba851f7 [DATABASE][TOOLS] Update local_user to return the proper PhoneNumber type 2021-09-14 13:05:45 +01:00
Hugo Sales
22e292276c [CORE][SECURITY][UX] Save previous url on /register and /logout 2021-09-14 13:05:45 +01:00
rainydaysavings
199fa0278c [CONTROLLER][UI] Fixing controller display errors, Settings CSS fixes 2021-09-14 13:05:45 +01:00
rainydaysavings
6d729de07c [UI][ROUTES][CONTROLLER] Fixing Settings navs and templates 2021-09-14 13:05:45 +01:00
rainydaysavings
a9b614bbdd [UI] Register and Login rework 2021-09-14 13:05:45 +01:00
rainydaysavings
e8d03e70ea [UI] Left panel fix 2021-09-14 13:05:44 +01:00
Hugo Sales
d08c4a1f62 [Controller] Update settings/avatar 2021-09-14 13:05:44 +01:00
Hugo Sales
db32a5fcfc [DATABASE][TOOLS] Update local_user, SchemaDefDriver and bin/generate_entity_fields to use the phone_number type (which maps to a varchar 35 and does validation) 2021-09-14 13:05:44 +01:00
Hugo Sales
db52e282b9 [UI] Update settings/account to reflect the current values 2021-09-14 13:05:44 +01:00
Hugo Sales
fd36e6fa7a [UI][ROUTES] s%settings/profile%settings/personal_info% 2021-09-14 13:05:44 +01:00
Hugo Sales
17f854b1d9 [CORE][UX] Save previous url to redirect back after registering 2021-09-14 13:05:44 +01:00
Hugo Sales
ead29a636d [DEPENDENCY] Add odolbeau/phone-number-bundle 2021-09-14 13:05:44 +01:00
Hugo Sales
576d6eb11c [UTIL][NICKNAME][FIX] Add self to constant 2021-09-14 13:05:44 +01:00
Hugo Sales
8b7dd48344 [UI][USERPANEL] Add prefilled fields, mark some as optional and handle self tags in the profile settings page 2021-09-14 13:05:44 +01:00
Hugo Sales
207eeb39ca [SELFTAGS] Add Profile::{set,get}SelfTags 2021-09-14 13:05:43 +01:00
Hugo Sales
1e911f1ba4 [FORM] Add Form::isRequired 2021-09-14 13:05:43 +01:00
Hugo Sales
6adb527fe0 [DATABASE] Refactor DB.php and make findBy always return an array, instead of a doctrine collection 2021-09-14 13:05:43 +01:00
Hugo Sales
040c400bfe [UTIL] Update Formatting::{toString,toArray} to allow spliting by either space or comma 2021-09-14 13:05:43 +01:00
Alexei Sorokin
66c38d777a [SECURITY] Update way passwords are checked and update 2021-09-14 13:05:43 +01:00
rainydaysavings
ea131d03e1 [TWIG][ROUTES] Footer links routes and pages added 2021-09-14 13:05:43 +01:00
rainydaysavings
fa613b7098 [UI][ROUTES] Footer links added 2021-09-14 13:05:43 +01:00
rainydaysavings
6d4f6b5109 [UI] Fixing problem due to Firefox's autofill filter 2021-09-14 13:05:43 +01:00
rainydaysavings
51f79242b7 [UI] Login template small fix 2021-09-14 13:05:43 +01:00
rainydaysavings
0dc3d3023e [UI] Left panel template and Login page CSS work done 2021-09-14 13:05:42 +01:00
Hugo Sales
3ba46a9a60 [SECURITY][CONTROLLER] Remove unreachable code from the Security controller 2021-09-14 13:05:42 +01:00
Hugo Sales
c26ffe09b6 [CONTROLLER][ADMIN][CONFIG] Fix form to use static strings as keys and add labels seperately; convert input from string to appropriate type 2021-09-14 13:05:42 +01:00
Hugo Sales
b772702895 [LIB][Util] Update Common::setConfig to throw an exception if appropriate, add Formatting::{toString,toArray} 2021-09-14 13:05:42 +01:00
Hugo Sales
647fd421ee [I18N] Remove incomplete autogenerated translation file, to be fixed later 2021-09-14 13:05:42 +01:00
Hugo Sales
91af1be470 [AUTOGENERATED] Update all entity fields 2021-09-14 13:05:42 +01:00
Hugo Sales
e0cc125907 [SECURITY] Small refactor in Authenticator.php, to remove unused services 2021-09-14 13:05:42 +01:00
Hugo Sales
c973517397 [USER][UI][AUTHENTICATION] Add registration form 2021-09-14 13:05:42 +01:00
Hugo Sales
17dc298dfa [UTIL][NICKNAME] Small refactor and remove the check between user nickname and group_alias, as these will have different semantics 2021-09-14 13:05:42 +01:00
Hugo Sales
5b578b9519 [DATABASE] Fix typos in user_notification_prefs 2021-09-14 13:05:42 +01:00
Hugo Sales
6e6c7ede1e [DATABASE] Fix typo in profile table and add a constructor 2021-09-14 13:05:41 +01:00
Hugo Sales
7c6112b887 [FORM][WRAPPER] Merge argument options, not replace 2021-09-14 13:05:41 +01:00
Hugo Sales
a85fc2d0bd [DATABASE] Update LocalUser table to not have a numerical id, add is_email_verified and fix getProfile accordingly 2021-09-14 13:05:41 +01:00
Hugo Sales
7a7f7d3ae1 [MAILER][WRAPPER] Add mailer wrapper that respects the configuration 2021-09-14 13:05:41 +01:00
Hugo Sales
7c35fde8bc [FIX] Fix bug in DATABASE.php, since findBy can return different types 2021-09-14 13:05:41 +01:00
Hugo Sales
72bf62adc3 [TOOLS] Update generate fields script to output default values 2021-09-14 13:05:41 +01:00
Hugo Sales
672e2b80eb [DEPENDENCY] Add symfonycasts/verify-email-bundle 2021-09-14 13:05:41 +01:00
Hugo Sales
c0da90bd3e [COMMON][SECURITY][WRAPPER] Added security service static wrapper and Common::getUser 2021-09-14 13:05:41 +01:00
Hugo Sales
97fd7620e7 [CORE][ROUTES] Small refactor on entrypoint and RouteLoader 2021-09-14 13:05:41 +01:00
Hugo Sales
1572261617 [TWIG] Add twig function to output the active tag if the current route matches a given one 2021-09-14 13:05:40 +01:00
Hugo Sales
cac00dd6d4 [CONTROLLER][ROUTES] Refactor the base Controller to not reinvent the wheel too much and rely on Symfony's events 2021-09-14 13:05:40 +01:00
Hugo Sales
a1c90f2e15 [ROUTES] Change name of admin and settings routes and refactor the way they're specified 2021-09-14 13:05:40 +01:00
Hugo Sales
56f74fffe8 [CONTROLLER][ROUTES] Refactor controllers to use the new base class and remove controller from the class name 2021-09-14 13:05:40 +01:00
Hugo Sales
2796ac5228 [NOTIFICATION][DATABASE] Update user notification prefs table, implementation of Notification and define a base class for notification transport 2021-09-14 13:05:40 +01:00
Hugo Sales
df4d246ede [CONTROLLER] Remove example enqueue 2021-09-14 13:05:40 +01:00
Hugo Sales
59fcd042e9 [DEFAULTS] Add password hashing algorithm default settings 2021-09-14 13:05:40 +01:00
Hugo Sales
0eba267a73 [LOGIN] Implement password checking and related systems 2021-09-14 13:05:40 +01:00
Hugo Sales
f3ccdf8017 [USER] Add UserRoles 2021-09-14 13:05:40 +01:00
Hugo Sales
5a74354703 [DATABASE] Add role collumn to profile table 2021-09-14 13:05:39 +01:00
Hugo Sales
8ce0f05371 [UTIL] Update Common::config to ensure the values queried exist 2021-09-14 13:05:39 +01:00
Hugo Sales
ae373c7d96 [DEFAULTS][FIX] Fix logic error that kept reloading the table when the file wasn't modified 2021-09-14 13:05:39 +01:00
Hugo Sales
3313897671 [UI][SESSION] Add login and logout pages 2021-09-14 13:05:39 +01:00
Hugo Sales
fb53700be2 [LIB][Util] Remove Functional::arity as it got merged upstream as Functional\ary 2021-09-14 13:05:39 +01:00
Hugo Sales
d6cd52cede [LIB][Util] Make Common::config return the unserialized value instead of the entity 2021-09-14 13:05:39 +01:00
Hugo Sales
284fbe2c5b [CORE] Refactor GNUsocial.php so it initializes itself as a service 2021-09-14 13:05:39 +01:00
Hugo Sales
e482ecfb87 [I18N] Remove support for context until it proves necessary, as it broke the code 2021-09-14 13:05:39 +01:00
Hugo Sales
028d7c929f [TOOLS] Update shebang on scripts to use the correct php executable 2021-09-14 13:05:39 +01:00
Hugo Sales
f246667fe5 [AUTOGENERATED] Update autogenerated code 2021-09-14 13:05:38 +01:00
Hugo Sales
7c8ab40e3a [DATABASE] Rename user table to local_user, since doctrine shits itself otherwise ._. 2021-09-14 13:05:38 +01:00
Hugo Sales
8f68bde21a [DEPENDENCY] Add symfony/config as a dependency 2021-09-14 13:05:38 +01:00
Hugo Sales
01b5c4b2f7 [CONFIG] Change way configuration is done to use Symfony's system instead of environment vars 2021-09-14 13:05:38 +01:00
Hugo Sales
fffa17448f [CORE][I18n][DEFAULTS] Remove I18nHelper 2021-09-14 13:05:38 +01:00
Hugo Sales
339003f210 [LIB][Util] Change methods in the Common class to camelCase, add isSystemPath (previously in Nickname.php) 2021-09-14 13:05:38 +01:00
Hugo Sales
d0771f77bc [UTIL][NICKNAME] Import nickname utilities and exceptions from v2 2021-09-14 13:05:38 +01:00
Hugo Sales
07c033de33 [DEFAULTS] Update default reserved usernames 2021-09-14 13:05:38 +01:00
Hugo Sales
3992629a08 [DATABASE][WRAPPER] Add findBy method which allows finding entities with a complex expression 2021-09-14 13:05:38 +01:00
Hugo Sales
0ac1d563de [DATABASE] Re-import the local_group table, as it'll be used as per the new group semantics 2021-09-14 13:05:37 +01:00
rainydaysavings
d6320943ce [UI] Settings routes refactor, avatar and misc settings added. 2021-09-14 13:05:37 +01:00
rainydaysavings
6dd966bd3f [UI][CONTROLLER][ROUTES] UserPanel account page form added, account page CSS work 2021-09-14 13:05:37 +01:00
rainydaysavings
5a53915f80 [UI] Fixed top header spacing issue, hamburger menu weird rendering 2021-09-14 13:05:37 +01:00
rainydaysavings
d0b04b6084 [UI] FAQ pages markdown fixes 2021-09-14 13:05:37 +01:00
rainydaysavings
c9f731507b [UI][CONTROLLER] Form help messages added, fixed checkbox trick hitbox 2021-09-14 13:05:37 +01:00
rainydaysavings
0dfb96cdeb [UI] Reset CSS added, small fixes all around 2021-09-14 13:05:37 +01:00
rainydaysavings
1558bffcac [UI] Settings page CSS redesign port completed 2021-09-14 13:05:37 +01:00
rainydaysavings
63a443e78e [UI][CONTROLLER][ROUTES] Corrected core action name, UserPanel CSS work 2021-09-14 13:05:37 +01:00
rainydaysavings
0b0bd31a4b [UI] Fixed FAQ template issues 2021-09-14 13:05:36 +01:00
rainydaysavings
19a96539aa [UI] Side panel animation added 2021-09-14 13:05:36 +01:00
rainydaysavings
22042a8cb7 [UI] Redesign responsiveness work done 2021-09-14 13:05:36 +01:00
rainydaysavings
f8fc226673 [UI] Further work into new side panel design 2021-09-14 13:05:36 +01:00
rainydaysavings
4eaf272929 [UI] Basic implementation of the new base design 2021-09-14 13:05:36 +01:00
rainydaysavings
115257f3bb [UI] Polishing FAQ CSS 2021-09-14 13:05:36 +01:00
rainydaysavings
0117883bd5 [UI] Standardization of sizes and variable usage for faster theming 2021-09-14 13:05:36 +01:00
rainydaysavings
02318d954c [UI][CONTROLLER] Profile settings action functionality working 2021-09-14 13:05:36 +01:00
Hugo Sales
643a937152 [DATABASE][WRAPPER] Update DATABASE wrapper so entity names are provided without the namespace 2021-09-14 13:05:36 +01:00
Hugo Sales
0615adbb51 [DOCKER] Add redis to the docker image 2021-09-14 13:05:36 +01:00
Hugo Sales
09c2a762ef [CACHE] Fix usage of the redis extension 2021-09-14 13:05:35 +01:00
Hugo Sales
c0a17af062 [DOCKER] Fix redis extension build process to use LZ4 and add APCu 2021-09-14 13:05:35 +01:00
Hugo Sales
4776cff969 [DEPENDENCY] Add mock polyfill implementations of the redis and memcached extension 2021-09-14 13:05:35 +01:00
Hugo Sales
31ad75564f [CACHE][Redis] Add special support for redis (fixed size lists), set method and general fixes 2021-09-14 13:05:35 +01:00
Hugo Sales
c602cf8422 [LIB][Util] Refactor and implement array indexing methods on RingBuffer 2021-09-14 13:05:35 +01:00
Hugo Sales
071c1aaec4 [DOCKER] Updated php image so redis is compiled with LZ4 compression available, as it's the fastest at decompressing and really fast at compressing. Read performance is more important, with this being used as a cache 2021-09-14 13:05:35 +01:00
Hugo Sales
c549bea4a9 [CACHE] Add support for multiple pools with the syntax (as an example) SOCIAL_CACHE_ADAPTER='default=redis://localhost:6379,memcached://localhost:11211;db.config=apcu://' 2021-09-14 13:05:35 +01:00
Hugo Sales
d35b6f3437 [DOCKER] Add msgpack and redis extensions to docker image 2021-09-14 13:05:35 +01:00
Hugo Sales
cfe1901b51 [DEFAULTS] Add modified time to config table (as value) and only reload the defaults if the file is newer 2021-09-14 13:05:35 +01:00
Hugo Sales
e91a141474 [CACHE] Extend the static wrapper to support working with lists in caches that don't natively support them 2021-09-14 13:05:34 +01:00
Hugo Sales
7f5e574cbf [LIB][Util] Add Ring Buffer data structure 2021-09-14 13:05:34 +01:00
Hugo Sales
05ffc0db9c [DOCKER] Move certbot files to hidden folder, so it's ignored by GNU global 2021-09-14 13:05:34 +01:00
Hugo Sales
0e0321cfef [DEFAULTS][FIX] Fix defaults to use value from environment 2021-09-14 13:05:34 +01:00
Hugo Sales
2671c37039 [PHP][EXTENSION][POLYFILL] Add php-ds polyfill, which is used if the native extension is not available 2021-09-14 13:05:34 +01:00
Hugo Sales
279b7e775b [DOCKER][PHP][EXTENSION] Add PHP ds extension to docker PHP image 2021-09-14 13:05:34 +01:00
Hugo Sales
52aad30030 [TOOLS][configure] Fix to use quotation marks properly 2021-09-14 13:05:34 +01:00
Hugo Sales
9d2f6e7425 [CACHE][WRAPPER] Fix cache wrapper 2021-09-14 13:05:34 +01:00
Hugo Sales
4f85594bec [FORMATTING][DEFAULTS] Fix formatting and remove redundant config defaults 2021-09-14 13:05:34 +01:00
Hugo Sales
b7b50f749b [CACHE][HTTP] Configure simple HTTP cache 2021-09-14 13:05:33 +01:00
Hugo Sales
65cc487a29 [CACHE] Add a static wrapper around symfony/cache 2021-09-14 13:05:33 +01:00
Hugo Sales
81dd2e4c72 [DEPENDENCY] Add symfony/cache as a dependency 2021-09-14 13:05:33 +01:00
Hugo Sales
aae883880f [LOG][WRAPPER] Refactor log wrapper 2021-09-14 13:05:33 +01:00
Hugo Sales
d48cb3f0b8 [QUEUE] Add queueing wrapper, default configuration and example usage 2021-09-14 13:05:33 +01:00
Hugo Sales
441fd8490f [DEPENDENCY] Add symfony/messenger as a dependency 2021-09-14 13:05:33 +01:00
Hugo Sales
9c483e6e79 [DATABASE] Delete queue_item table, as queueing will be handled by messenger 2021-09-14 13:05:33 +01:00
Hugo Sales
423129486c [CONTROLLER] Show dummy notices in main/all 2021-09-14 13:05:33 +01:00
Hugo Sales
8e30b9423b [MODULES] Make ModulesManager check if file exists 2021-09-14 13:05:33 +01:00
Hugo Sales
59b2b98537 [CONTROLLER] Add Controller base class, which handles rendering templates if requested HTML or json, accordingly 2021-09-14 13:05:32 +01:00
Hugo Sales
a56c7934ec [ROUTE] Fix routes, config_admin got deleted 2021-09-14 13:05:32 +01:00
Hugo Sales
936d13d966 [COMMAND][DEPRECATION][FIX] Fix app:events's deprecation 2021-09-14 13:05:32 +01:00
Hugo Sales
3483be1770 [GIT] Update gitignore to ignore composer.local.json, where plugin settings will be placed 2021-09-14 13:05:32 +01:00
Hugo Sales
e97ba23a99 [DEPENDENCY] Update all dependencies 2021-09-14 13:05:32 +01:00
Hugo Sales
5b5ca6ccea [DEPENDENCY] Add wikimedia/composer-merge-plugin as a dependency, to allow managing plugins 2021-09-14 13:05:32 +01:00
rainydaysavings
ac46c14344 [DEPENDENCY] Add erusev/parsedown and twig/markdown-extra as dependencies 2021-09-14 13:05:32 +01:00
rainydaysavings
81e8173ed4 [TWIG][CONFIG] Change default_path and add public_path 2021-09-14 13:05:32 +01:00
rainydaysavings
996f2338a5 [CONTROLLER] UserAdminPanel handle request fix
[UI] Minor CSS font size corrections
2021-09-14 13:05:32 +01:00
rainydaysavings
82d50cc962 [TWIG][UI] Settings: removed unnecessary pages, responsive CSS work 2021-09-14 13:05:32 +01:00
rainydaysavings
1498c44e74 [UI][CONTROLLER] Settings page styling almost done. 2021-09-14 13:05:31 +01:00
rainydaysavings
79b9e66315 [TWIG] faq/contact template route fix 2021-09-14 13:05:31 +01:00
rainydaysavings
8674d20327 [FAQ] Removing unnecessary categories. 2021-09-14 13:05:31 +01:00
rainydaysavings
22b68766db [UI][FAQ] FAQ polish, better use of twig, responsive css. 2021-09-14 13:05:31 +01:00
rainydaysavings
17d737b590 [UI][Mobile][FAQ][ROUTES] FAQ sub pages and routing added, small screen css work started. 2021-09-14 13:05:31 +01:00
rainydaysavings
768607fe98 [UI] Icon assets now work with Symfony asset component, header icon placement fixes 2021-09-14 13:05:31 +01:00
rainydaysavings
432dfdd0ae [UI][ROUTES][CONTROLLER] Settings pages routes and styling done. 2021-09-14 13:05:31 +01:00
rainydaysavings
f3e9671b1a [UI] Work started on profile settings page. 2021-09-14 13:05:31 +01:00
rainydaysavings
6cf90954dd [UI][Header] New header implemented. 2021-09-14 13:05:31 +01:00
rainydaysavings
ad107542d9 [TWIG][UI] CSS refactoring, containerized twig blocks and settings initial work 2021-09-14 13:05:30 +01:00
rainydaysavings
bf0e944aaa [TWIG] FAQ base template hierarchy fixes
Minor refactoring of routes for FAQ static pages
2021-09-14 13:05:30 +01:00
rainydaysavings
02ddf96371 [UI][ROUTES] Better use of icons, fixing static pages routing. 2021-09-14 13:05:30 +01:00
rainydaysavings
1989cb481a [UI][FAQ] Better FAQ organization, removing unnecessary categories. 2021-09-14 13:05:30 +01:00
rainydaysavings
727083ec88 [UI][Mobile][FAQ] FAQ polish, better use of twig, responsive css. 2021-09-14 13:05:30 +01:00
rainydaysavings
ecd7aedf0c [UI][Mobile][FAQ] FAQ sub pages and routing added, small screen css work started. 2021-09-14 13:05:30 +01:00
rainydaysavings
aac90a9c9e [UI] SVG icons added
[TWIG][UI] Header completed
2021-09-14 13:05:30 +01:00
rainydaysavings
9d36861076 [UI][FAQ] FAQ page progress, assets folder and assets added 2021-09-14 13:05:30 +01:00
rainydaysavings
124e1a70c1 [UI][FAQ] Controller and Route for FAQ page created as well as basic template structure 2021-09-14 13:05:30 +01:00
Hugo Sales
0eb0d21007 [TOOLS] Fix bootstrap and pre-commit scripts 2021-09-14 13:05:29 +01:00
Hugo Sales
4d92915846 [MODULE] Move 'foreign' entities from core to a module 2021-09-14 13:05:29 +01:00
Hugo Sales
97b583aee7 [AUTOGENERATED] Update autogenerated code 2021-09-14 13:05:29 +01:00
Hugo Sales
2eab90bbb0 [TOOLS] Update bin/generate_entity_fields script 2021-09-14 13:05:29 +01:00
Hugo Sales
5eae3dc351 [CORE][DATABASE] Replace zero dates with CURRENT_TIMESTAMP and add defaults to all 'created' or 'modified'
This commit is a port from v2's 9a515b9234 ([SCHEMA] Improve timestamp storage) to v3.

As explained by Alexei Sorokin:

Avoid the use of deprecated MariaDATABASE "zero dates" globally. If they're present
as attribute defaults somewhere, they will be replaced with NULL implicitly.
The existing "zero dates" in MariaDATABASE storage will be left intact and this
should not present any issues.

The "timestamp" type in table definitions now corresponds to DATETIME in
MariaDATABASE with "DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP", which
should be close enough to the original behaviour for compatibility purposes.
It is now the recommended type for "modified" attributes, because of the
update trigger on MariaDATABASE. But there is no such trigger implemented on
PostgreSQL as of this moment.
2021-09-14 13:05:29 +01:00
Hugo Sales
25aeac80a3 [CORE][DATABASE] Restructure the database 2021-09-14 13:05:29 +01:00
Hugo Sales
44eaf43ba9 [ROUTE][ADMIN][CONFIG] Add route to update values in the config table 2021-09-14 13:05:29 +01:00
Hugo Sales
e286f39551 [DEFAULTS] Small fixes and add check of SOCIAL_NO_RELOAD_DEFAULTS from the environment, to override the reloading of default values 2021-09-14 13:05:29 +01:00
Hugo Sales
84be8e1711 [DOCUMENTATION] Fixed type annotations and documentation of Common::size_str_to_int 2021-09-14 13:05:29 +01:00
Hugo Sales
b7a8861f55 [CORE][Event] Move GSEvent to Event, no longer a name collision 2021-09-14 13:05:28 +01:00
Hugo Sales
b32e173749 [FORM] Added Symfony Form wrapper 2021-09-14 13:05:28 +01:00
Hugo Sales
bc6ead4ab1 [CORE][Symfony] Fixed deprecation resultant from Symfony 5.1 upgrade
User Deprecated: Since symfony/framework-bundle 5.1: Using type
"Symfony\Component\Routing\RouteCollectionBuilder" for argument 1 of
method "App\Kernel:configureRoutes()" is deprecated, use
"Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator"
instead.
2021-09-14 13:05:28 +01:00
Hugo Sales
7a52c1d823 [TESTS][I18N] Added test for I18n::_m and I18nHelper::formatICU 2021-09-14 13:05:28 +01:00
Hugo Sales
753f852941 [I18N] Fix implementation of I18nHelper::formatICU 2021-09-14 13:05:28 +01:00
Hugo Sales
491e82f94e [ROUTES] Add easier support for using TemplateController and improved documentation 2021-09-14 13:05:28 +01:00
Hugo Sales
f28ff24f2a [I18N] Small fixes. Still broken, though :') 2021-09-14 13:05:28 +01:00
Hugo Sales
fb457d4a45 [AUTOLOAD] Always autoload _m file 2021-09-14 13:05:28 +01:00
Hugo Sales
8649b72192 [DEPENDENCY] Upgrade Symfony framework from 5.0 to 5.1 2021-09-14 13:05:28 +01:00
Hugo Sales
db5811a77e [DEPENDENCY][DEV] Added Symfony Bridge PHPUnit 2021-09-14 13:05:27 +01:00
Hugo Sales
4133fc3290 [GIT] Updated gitignore 2021-09-14 13:05:27 +01:00
Hugo Sales
10ca51e72a [I18N] Overhaul _m() implementation to support ICU message formats 2021-09-14 13:05:27 +01:00
Hugo Sales
a65a46f14e [I18N] Dumped english translation files 2021-09-14 13:05:27 +01:00
Hugo Sales
e3d8ea7912 [TOOLS] Small fix to composer install hook 2021-09-14 13:05:27 +01:00
Hugo Sales
711af58dcd [I18N] Added ability to call _m_dynamic from any class, allowing it to define translations for dynamic-valued calls to _m 2021-09-14 13:05:27 +01:00
Hugo Sales
5be901f9ce [TOOLS] Improve configure script to disallow reserved database names 2021-09-14 13:05:27 +01:00
Hugo Sales
dc7387cc8d [I18N] Custom translation extractor based on Symfony's PhpExtractor, since we use instead of 2021-09-14 13:05:27 +01:00
Hugo Sales
f283613443 [I18N] Refactor since rfc/use-static-function is not implemented
As the above mentioned RFC is not implemented, `_m` needs to be
outside of the I18n class, otherwise it would have to always be called
with `I18n::_m`.
2021-09-14 13:05:27 +01:00
Hugo Sales
186b9e7683 [ROUTES] Add static wrapper around Symfony's router 2021-09-14 13:05:27 +01:00
Hugo Sales
4ffb7c338f [CORE] Refactoring core 2021-09-14 13:05:26 +01:00
Hugo Sales
87bc60a806 [UI][CONFIG] Added admin configuration form 2021-09-14 13:05:26 +01:00
Hugo Sales
436b44df89 [I18N] Fix i18n and add default domain 'Core' 2021-09-14 13:05:26 +01:00
Hugo Sales
13ae29cae2 [DEFAULTS] Fix default config loading logic 2021-09-14 13:05:26 +01:00
Hugo Sales
7c18f10bd2 [TOOLS] Fixed all licence blocks, to use the same, foldable, format 2021-09-14 13:05:26 +01:00
Hugo Sales
82ae4f8920 [DEPENDENCY] Added alchemy/zippy, which adds support for multiple archive formats. Used to allow theme uploads in zip, tar, gz, or other formats 2021-09-14 13:05:26 +01:00
Hugo Sales
02db154495 [DOCUMENTATION][DEFAULTS] Documented all defaults and updated some. Restructured other documentation. 2021-09-14 13:05:26 +01:00
Hugo Sales
4deb446f39 [DEFAULTS] Remove deprecated defaults and convert them to snake_case 2021-09-14 13:05:26 +01:00
Hugo Sales
6cc19b83df [GIT] Added docker-compose to gitignore, in preparation for using a script to generate them 2021-09-14 13:05:26 +01:00
Hugo Sales
a794c28e75 [DATABASE] Change the way defaults are loaded, bulk insert, reload everything in debug mode, only on http requests (not command line) 2021-09-14 13:05:25 +01:00
Hugo Sales
5a61098d28 [TOOLS] Update install scripts 2021-09-14 13:05:25 +01:00
Hugo Sales
988be9dbf1 [DATABASE] Fix 'relation config doesn't exist' 2021-09-14 13:05:25 +01:00
Hugo Sales
0ccc359880 [DATABASE] Postgres doesn't understand '0000-00-00 00:00:00' for datetime, use '-infinity' 2021-09-14 13:05:25 +01:00
Hugo Sales
aaf38353ea [DOCKER] Change postgres data path to the correct one 2021-09-14 13:05:25 +01:00
Hugo Sales
b9bc88ddbf [DATABASE][CONFIG] Loading defaults into database, doctrine static wrapper 2021-09-14 13:05:25 +01:00
Hugo Sales
cdb863ba17 [DATABASE][CONFIG] Bring default configs from V2 and implement DATABASE wrapper 2021-09-14 13:05:25 +01:00
Hugo Sales
736a1f7012 [ASSETS] Import old favicon.ico 2021-09-14 13:05:25 +01:00
Hugo Sales
dd559402cd [CORE][UTIL] Moved classes from util to core
And splitted up Common
2021-09-14 13:05:25 +01:00
Hugo Sales
f628665589 [FORMATTING] Cherry-pick of Diogo's 763ac735c0758624ebd5957993dc0676b865927a 2021-09-14 13:05:24 +01:00
Diogo Cordeiro
f60e37ba3d [DOCKER][BOOTSTRAP] Add option to use a self signed cert 2021-09-14 13:05:24 +01:00
Diogo Cordeiro
cb7518a750 [DOCUMENTATION][TOOL] Small bug fixes and docblock elaboration 2021-09-14 13:05:24 +01:00
Hugo Sales
243aefe683 [CORE] Rename GNU social constants 2021-09-14 13:05:04 +01:00
Hugo Sales
09e70da366 [DOCUMENTATION] Updated INSTALL.md to reflect the fact that a CNAME record can be used directly 2021-09-14 13:05:04 +01:00
Hugo Sales
9449dd26c5 [DOCUMENTATION] Import installation instructions for installing without docker from V2 2021-09-14 13:05:04 +01:00
Hugo Sales
1ce5661f70 [DOCKER] Small fixes to docker setup, imported from V2 2021-09-14 13:05:03 +01:00
Hugo Sales
bf88c97f4a [DOCUMENTATION] Added a code walkthrough document, which explains how the codebase works 2021-09-14 13:05:03 +01:00
Hugo Sales
0620d9a726 [DOCUMENTATION] Added install documentation 2021-09-14 13:05:03 +01:00
Hugo Sales
8a86c5940d [TOOLS] Updated install script to also support mariadb 2021-09-14 13:05:03 +01:00
Hugo Sales
50e450f082 [TOOLS][DOCKER] Further fixes in the docker environment and fixed the install script 2021-09-14 13:05:03 +01:00
Hugo Sales
b1afa9cf91 [DOCKER] Fixed docker environment to properly configure the app environment 2021-09-14 13:05:03 +01:00
Hugo Sales
cf1a9fe893 [TOOLS] Added script to configure the installation and to bootstrap certificate creation with Let's Encrypt 2021-09-14 13:05:03 +01:00
Hugo Sales
e0b26ad38b [TOOLS][SSL] Added bin/boostrap_certificates.sh, allowing for easy configuration of SSL certificates with Let's Encrypt 2021-09-14 13:05:03 +01:00
Hugo Sales
06b5fe2cdf [TOOLS][DOCUMENTATION] Improvements to entity generation script 2021-09-14 13:04:39 +01:00
Hugo Sales
cbbdae6831 [DOCUMENTATION] Added generated diagram 2021-09-14 13:04:39 +01:00
Hugo Sales
bb5cdc03e4 [DOCUMENTATION][TOOLS] Wrote a tool to generate entity diagrams from the database definition 2021-09-14 13:04:39 +01:00
Hugo Sales
a7cc7f4e27 [UTIL] Wrote HTML library to convert arrays to html 2021-09-14 13:04:39 +01:00
Hugo Sales
8ff0f230ed [GITIGNORE] Add file folder to gitignore 2021-09-14 13:04:39 +01:00
Hugo Sales
fe73001c36 [DATABASE] Changed the type of the 'id' field of the ProfileList table from serial to int, as doctrine complains otherwise 2021-09-14 13:04:39 +01:00
Hugo Sales
afc4e87353 [TOOLS][CS-FIX] Altered some php-cs-fix rules 2021-09-14 13:04:38 +01:00
Hugo Sales
1f35af7169 [DATABASE][AUTOCODE] Update autocode to use \DateTimeInterface instead of DateTime 2021-09-14 13:04:38 +01:00
Hugo Sales
c583c0f266 [TOOLS] Fix the generate_entities_fields script 2021-09-14 13:04:38 +01:00
Hugo Sales
42321b936f [SCHEMADEF] Bug fixes 2021-09-14 13:04:38 +01:00
Hugo Sales
eee803d2e9 [DATABASE] Add missing table names 2021-09-14 13:04:38 +01:00
Hugo Sales
e022a5e65e [MODULES] Fix small error in modules manager 2021-09-14 13:04:38 +01:00
Hugo Sales
6193062590 [DATABASE][AUTOCODE] Autogenerated fields, setters and getters for each entity 2021-09-14 13:04:38 +01:00
Hugo Sales
55bc66d7ed [TOOLS][AUTOCODE] Fixed generate_entities script 2021-09-14 13:04:38 +01:00
Hugo Sales
7e47846b80 [TOOLS] Change autocode tag to allow editor folding 2021-09-14 13:04:38 +01:00
Hugo Sales
f1e72255f1 [DATABASE] Removed calls to common_config 2021-09-14 13:04:37 +01:00
Hugo Sales
03a8c80c4f [FORMATTING] Changed license block format to allow folding 2021-09-14 13:04:37 +01:00
Hugo Sales
8d41944f90 [DATABASE] Extracted schemaDef method from old files and refactored onto new files 2021-09-14 13:04:37 +01:00
Hugo Sales
c38b9a1503 [COMMON] Added toCamelCase and toSnakeCase functions 2021-09-14 13:04:37 +01:00
Hugo Sales
98a5b89e42 [TOOLS] Add script used to port from old class files to entities 2021-09-14 13:04:37 +01:00
Hugo Sales
24c8fefe58 [CORE][DATABASE] Import old classes folder into src/Entity 2021-09-14 13:04:37 +01:00
Hugo Sales
8fd54efe8d [DATABASE] Remove testing entity 2021-09-14 13:04:37 +01:00
Hugo Sales
1c3ed4cddb [TOOLS] Add command which imports a file with it's history 2021-09-14 13:04:37 +01:00
Hugo Sales
0c79dfc67b [MODULES] Rename extensions to modules, add example plugin, change plugin location 2021-09-14 13:04:37 +01:00
Hugo Sales
596009c924 [DOCUMENTATION] Document All The Things! 2021-09-14 13:04:33 +01:00
Hugo Sales
5d1685b142 [CORE][ROUTES] Implemented custom router, with an interface similar to the old one, which allows routes to be seperated into files 2021-09-14 13:01:35 +01:00
Hugo Sales
e92a0227a1 [COMMAND][EVENTS] Added command to list events and handlers, and search by regex 2021-09-14 13:01:35 +01:00
Hugo Sales
b50909a335 [CORE][COMMAND] Register internal structures on command event 2021-09-14 13:01:34 +01:00
Hugo Sales
6df658a987 [CORE][EXTENSIONS] Added extension (modules, plugins) loading and test plugin, which is able to handle events 2021-09-14 13:01:34 +01:00
Hugo Sales
cfc269aca4 [CORE][SCHEMADEF] Clean up SchemaDef compiler pass 2021-09-14 13:01:34 +01:00
Hugo Sales
23b47b2aeb [CS-FIXER] Updated cs-fixer rules and added a temporary exception to the src/Entity folder (awaiting pr merge) 2021-09-14 13:01:34 +01:00
Hugo Sales
e3c0669b37 [DOCTRINE][SCRIPT] Created a script to generate the class fields and accessors from the schema definition 2021-09-14 13:01:34 +01:00
Hugo Sales
1b45936f19 [DOCTRINE][SCHEMADEF] Small refactoring 2021-09-14 13:01:34 +01:00
Hugo Sales
2c9a732256 [CORE][DOCTRINE] Implement SchemaDefDriver, which transforms the old syntax from to doctrine's metadata 2021-09-14 13:01:34 +01:00
Hugo Sales
4d7c8628f6 [DOCTRINE] Configure cli-config for doctrine console and ensure DATABASE is set to UTF-8 2021-09-14 13:01:34 +01:00
Hugo Sales
cc72373e3d [DOCTRINE][SCHEMADEF] Create a new metadata driver to allow us to continue using static schemaDef functions
This has the benefit of requiring fewer code changes, as well as providing a better isolation
between GNU social and symfony, useful in case the framework needs to be changed
2021-09-14 13:01:34 +01:00
Hugo Sales
710aa946ab [COMPOSER] Update composer dependencies 2021-09-14 13:01:33 +01:00
Hugo Sales
2215b05894 [CORE][I18N] Fix the translation system 2021-09-14 13:01:33 +01:00
Hugo Sales
2b9a15c1e9 [CORE][I18N] Port the translation system to rely on symfony's 2021-09-14 13:01:33 +01:00
Hugo Sales
feaee1b238 [CORE][EVENTS] Bring existing Events and Boostrapper back
- Adapt the existing event system to rely on Symfony's event dispatcher
2021-09-14 13:01:33 +01:00
Hugo Sales
b396f1227a [CORE][ROUTES] Example route 2021-09-14 13:01:33 +01:00
Hugo Sales
7da61f8db5 [DOCKER] Updated dockerfile to add memcached 2021-09-14 13:01:33 +01:00
Hugo Sales
d6bb3e7caa [DOCKER] Added preliminary docker container 2021-09-14 13:01:33 +01:00
Hugo Sales
633a3b0773 [COMPOSER] Update composer packages 2021-09-14 13:01:33 +01:00
Hugo Sales
4b31c1f48f [V3] Big Bang
Beginning anew, this time with a modern framework: symfony
2021-09-14 13:01:33 +01:00
11154a0d8c [V3] Big Crunch
And so, just as it begins, so too must it end
One should not dwell and stall, for more is to come
2021-09-14 13:01:23 +01:00
50dd4fee0e [CORE] Bump PHP version to 7.4 2021-07-18 13:08:41 +01:00
7d8988d50c [VersionBump] 2.0.0beta0
Updated composer and translations

composer install --no-dev
composer dump-autoload --optimize
git add vendor/ --force
make updatepo
2021-07-18 12:51:07 +01:00
Maiyannah Bishop
58d9b91dd3 [API] Security hotfix for source, picked from postActive 2021-07-17 20:25:36 +01:00
b6bcd3b8c0 [PEAR] Force using extlib's patched version 2021-07-16 18:31:30 +01:00
31433db539 [ActivityPub][POSTMAN] Do not die on network errors 2021-07-16 18:03:12 +01:00
bdb4c54fa8 [DirectMessage] Fix some wrong calls after MessageModel introduction in d9a9a3746b 2021-07-16 17:36:33 +01:00
55293e4008 [ActivityPub][INBOX] CREATE NOTE Attachments, we handle enclosures elsewhere
It was trying to make enclosures with objects instead of strings, also attachments don't use this, only links
2021-07-16 17:07:13 +01:00
066dfbb66d [MEDIA][MediaFile] Prevent issues with huge original filenames 2021-07-16 15:48:02 +01:00
bb2c845f62 [ActivityPub][INBOX] CREATE NOTE now accepts <br> tag 2021-07-16 15:48:02 +01:00
fbeadc1d49 [StoreRemoteMedia][SCRIPTS] Fix typo in query
This was introduced in 11ebb98919f56f7dcf888adfbebf9e8826f995b4#diff-96141878409d7418ea5a9eefbde509b43482c01R70
The arg number should have been one, as there's only one...
2021-07-16 15:46:25 +01:00
Alexei Sorokin
b6ce12a267 Update the project homepage and IRC channel 2021-06-12 11:30:12 +03:00
3b86f06134 [INSTALL] Update mailing list URL, as recommended by @Gijs
Closes notabug issue #327
2021-05-10 13:56:16 +00:00
b4b71f7626 [StoreRemoteMedia] Fix failing to show remote thumbnails on first load
imgPath onCreateFileImageThumbnailSource would throw FileNotFoundException
2021-04-13 14:58:55 +01:00
f088a3d54f [Embed] Apply encoding and increased type strictness patches from StoreRemoteMedia 2021-04-13 14:55:45 +01:00
5b23781e68 [StoreRemoteMedia] Gracefully recover from poorly encoded images 2021-04-13 14:54:56 +01:00
edc9fd203d [StoreRemoteMedia] Increase type strictness 2021-04-13 14:54:56 +01:00
844ecbf71e [Embed] Revert defaults and fix Readme example 2021-02-21 20:20:48 +00:00
8570ad2094 [StoreRemoteMedia][SCRIPTS] Move removeRemoteMedia deleteRemoteMedia 2021-02-21 16:03:47 +00:00
bc3eb7bccc [MEDIA] Allow thumbnail only entries 2021-02-21 16:03:47 +00:00
800c0daafe [StoreRemoteMedia][SCRIPTS] Update removeRemoteMedia 2021-02-21 16:03:47 +00:00
9b1ccdc320 [SCRIPTS] Update clean_file_table 2021-02-21 16:03:47 +00:00
6c8e826028 [MEDIA][SCRIPTS] clean_thumbnails Allow to delete remote thumbs as well
If the sysadmin decides that StoreRemoteMedia plugin should store
original, then its thumbs will be regenerated as well, making it safe to
delete them if needed. Beware that Embed plugin never stores the original tho.
2021-02-21 16:03:46 +00:00
d47bb3736e [Media] Document recently added settings and add some more
Fix some buggy ones, especially Embed crop
2021-02-21 16:03:46 +00:00
ec1719e61d [StoreRemoteMedia][Embed] Bump plugins version 2021-02-21 16:03:46 +00:00
a657a7809a [Media] Upload of previously uploaded files now works (bug fix)
This bug was introduced with the commit "[Media] Fix issues with database file storage"
due to the API change "File::getByHash now returns a yield of files".

I had updated this function on that commit but had missed this little detail.
2021-02-21 16:03:46 +00:00
ef0f65720e [StoreRemoteMedia] Remote images are now stored exactly on the necessary size for the thumb 2021-02-21 16:03:46 +00:00
22b5dd8567 [Media] Fix several issues
[StoreRemoteMedia] Upgrade plugin to use the new Media system

API Changes:
- Added getters to File to better formalize the ideas of the commit "[Media] Fix issues with database file storage"

UI Changes:
- Now presented thumbnails are actual thumbnails (bug fix)
- Attachment actions have a slightly more extended behaviour

Many other minor bug fixes...
2021-02-21 16:03:46 +00:00
f9290705f8 [ActivityPub] Attachment fetch should happen on StoreRemoteMedia 2021-02-21 16:03:46 +00:00
e51520bd63 [Core] Add an event for StoreRemoteMedia and Embed 2021-02-21 16:03:46 +00:00
6028175bfc [Media] Fix issues with database file storage
Fixed file quota as well.

There can be more than one file for the same filehash IF the url are different.

Possible states:
  - A file with no url and with filename is a local file.
  - A file with an url but no filename is a remote file that wasn't fetched,
    not even the thumbnail.
  - A file with an url and filename is a fetched remote file (maybe just a
    thumbnail of it).
  - A file with no filename nor url is a redirect.

Routes:
  Given these states, updated routes so that an attachment can only be
  retrieved by id and a file by filehash.

Major API changes:
  File::getByHash now returns a yield of files

Major UI changes:
  - Now remote non stored files are presented.
  - /view became preferred
  - Redirects to remote originals are preferred.

Many other minor bug fixes...
2021-02-21 16:03:46 +00:00
e9cd437668 [DOCUMENTATION] git clone with https so people don't need an account 2021-02-21 15:57:00 +00:00
aa153f2ee7 [i18n] Re-add gettext emulation
Removed by mistake with 9cc7df51d6#L50
2021-02-21 15:38:49 +00:00
b1e6b00545 [ActivityPub] Re-implement Delete Actor 2021-02-21 15:00:58 +00:00
Diogo Cordeiro
4f0ddc85d3 Merge branch 'ukrainian-translation-fix-branch' of tokarskiy/gnu-social into nightly 2020-12-31 11:20:15 +00:00
Andrew Tokarskiy
5d45702d5f Added some ukr translations 2020-12-31 10:17:45 +02:00
Andrew Tokarskiy
d731a5cb09 Fixed some ukrainian translation errors 2020-12-30 20:00:00 +02:00
Alexei Sorokin
06dfd91a82 Various fixes
Fix OAuth and Realtime issues introduced in 9a515b9234

[DATABASE] Fix an empty default value mistake introduced in
fde929b151

[DATABASE][PostgreSQL] Avoid use of pg_constraint.consrc, which was removed in
PostgreSQL 12.

[DATABASE][MariaDB] Fix a typo introduced in aed2344bd4

[DAEMON] Wrap an assignment inside "switch":
a follow-up to adc689cb15
2020-10-11 18:29:47 +03:00
Alexei Sorokin
c540466147 [XMPP] Respond to ping and track time monotonically
This also fetches a necessary update from the XMPPHP upstream.
2020-09-27 00:16:08 +03:00
Alexei Sorokin
4d8b04cda9 Clear out potential duplicates when semi-joining a union
Using a left outer join as a semi-join is not a valid approach.
Can still be used for an anti-semi-join.
2020-09-21 22:25:33 +03:00
Alexei Sorokin
aed2344bd4 Set the character set before making a connection
Ideally the character set should be set with the connection, and so this is
exactly what's being done now.

And now the character set code is attempted to be generalised.
2020-09-16 19:34:49 +03:00
SENOO, Ken
c2508f8fa2 Change required MySQL database character set variable
Changing `character_set_server` requires root permissions and rebooting
the server.

Which is impossible on shared web hosting services.

So use `character_set_database`. This variable can be changed with
user permissions using `ALTER DATABASE`.
2020-09-16 17:14:58 +03:00
Alexei Sorokin
52d67b0f44 Avoid ordering just by a timestamp
Try to also employ an id when possible.
Involves reworking some of the indices.
2020-09-15 16:59:27 +03:00
Alexei Sorokin
8079a476b6 Remove "magic quotes" code and avoid wrong order implode
"Magic quotes" were removed in PHP 5.4, no need to mitigate it anymore.

Avoid implode() with the join()-like order of arguments which was deprecated
since PHP 7.4 and implicitly since PHP 5.3.
Also avoid implode() with an implicit separator for stylistic reasons.

mktime() with no arguments has been deprecated since PHP 5.1.
2020-09-15 14:59:27 +03:00
Alexei Sorokin
2ef944d5c4 [UTIL] Sanitise instead of validate in common_copy_args()
And remove common_validate_utf8() which is now unused.
2020-09-15 14:53:35 +03:00
Alexei Sorokin
fde929b151 [DATABASE] Switch from PEAR DB to MDB2 2020-09-14 22:46:29 +03:00
Alexei Sorokin
96f1cc1a5c [ActivityPub][INBOX][Delete] Stop if the ID is not present 2020-09-14 21:32:41 +03:00
Alexei Sorokin
647bf8c953 [ActivityPub] Fix use of ActivityPubPlugin::pull_remote_profile
It does not throw but return null.
2020-09-14 20:48:10 +03:00
Alexei Sorokin
d2c7d70f49 Fix "Implement a class for automatic temporary file handling"
TemporaryFile::commit throws instead of returning a bool.
2020-09-14 20:37:48 +03:00
Alexei Sorokin
001629b6dd [Memcached_DataObject] Do not encache on insert
This resulted in N=0 and empty "modified" in cache.
2020-09-14 20:19:17 +03:00
Alexei Sorokin
b04469a252 [DATABASE] Make sure the session always uses UTF-8 and UTC 2020-09-12 15:40:39 +03:00
Alexei Sorokin
54484e56e7 [API] Fix /api/statuses/update reporting a failure 2020-09-12 13:58:57 +03:00
Alexei Sorokin
adc689cb15 Avoid use of assignments bare inside statements
Either use them in a subroutine call or put parentheses around the assignment.
2020-09-08 12:42:51 +03:00
Alexei Sorokin
d0f96a7023 [Profile] Extend the allowed length of nicknames to 191 characters 2020-09-06 21:20:24 +03:00
Alexei Sorokin
08145f635f Implement a class for automatic temporary file handling
And adopt it all over the code.
2020-09-04 13:15:23 +03:00
Alexei Sorokin
4884a97223 [Memcached_DataObject] Change how multiGet achieves an ordered result
The previous approach sent the key values twice, which for large sets is
twice as bad.

As an optional feature of this approach multiGet now allows retrieving tuples
in exact order and amount of the requested key values.
2020-09-03 18:11:12 +03:00
Alexei Sorokin
55136c1c6f [DirectMessage] Simplify the inbox query 2020-09-02 15:12:20 +03:00
Alexei Sorokin
fc300607e5 [ActivityPub] Check if a Notice is public via CC as well 2020-09-01 01:20:13 +03:00
Diogo Cordeiro
8c20ed0c89 [ActivityPub] Fix note URIs 2020-08-31 22:18:49 +01:00
Diogo Cordeiro
c8e9cbdbb8 [ActivityPub] Tombstones now have datetimes 2020-08-30 01:59:38 +01:00
Diogo Cordeiro
3f70ac5cde [TheFreeNetwork] Fix invalid index on lookup 2020-08-30 01:59:35 +01:00
Diogo Cordeiro
11a7182594 [ActivityPub] Implement Failed Queue 2020-08-29 20:32:21 +01:00
Diogo Cordeiro
817074a787 [ActivityPub] Fix DELETE 2020-08-29 20:32:18 +01:00
Diogo Cordeiro
c75bf1a19d [ActivityPub] Fix issues concerning Activity URIs
And some other minor bugs.
2020-08-29 11:29:12 +01:00
Alexei Sorokin
11ebb98919 [DATABASE] Fix use of ORDER BY with DISTINCT
statuses/retweets_of_me has performance fixed, so it is also stripped of its
"bad query" status.
2020-08-27 11:15:39 +03:00
Diogo Cordeiro
e4093343c2 [ActivityPub] Revert moving Disfavor to Queues
It seems this kind of notice isn't queued?
2020-08-27 02:14:47 +01:00
Diogo Cordeiro
101ea554ef [ActivityPub][Queues] Fix Like 2020-08-27 02:12:22 +01:00
Diogo Cordeiro
ef6a986dc6 [TheFreeNetwork] Do not allow lower priority protocols to handle remote actors already handled by the higher ones 2020-08-27 01:32:15 +01:00
Alexei Sorokin
db593496a7 [Directory] Fix SQL string quotation 2020-08-26 16:27:35 +03:00
Alexei Sorokin
00c492891e [Foreign_link] Change the type of "credentials" to blob
TwitterOAuthClient::packToken uses \0 as a delimeter which can cause issues on
TEXT or VARCHAR.
2020-08-25 16:06:37 +03:00
Alexei Sorokin
0e81f9c726 [OpenID] Correct table definition types
"server_url" should not be blob.
Lengths are adjusted to Auth/OpenID/(PostgreSQL|MySQL)Store.php.
2020-08-24 16:27:44 +03:00
Alexei Sorokin
b419c5cf7c [Queue_item] Let DataObject construct WHERE IN 2020-08-24 16:16:00 +03:00
Alexei Sorokin
20e5a6d1f3 [TwitterBridge][DAEMONS] Fix database connection clean-up 2020-08-24 15:43:14 +03:00
Alexei Sorokin
99a9a5d850 [NOTICES] Condition pushdown in the subquery in inboxnoticestream
This improves performance on PostgreSQL.
2020-08-19 19:14:11 +03:00
Alexei Sorokin
a15d51c3d8 [DATABASE][PostgreSQL] Ignore index prefix length 2020-08-17 17:01:42 +03:00
Alexei Sorokin
b01974b665 [PostgreSQL] Set timezone to UTC
And remove some redundant neighbouring cruft:
utf8mb4 is already set in mysqlschema more than enough times.
2020-08-17 16:52:11 +03:00
Alexei Sorokin
be5bec9887 Rename the mysql_foreign_keys option to foreign_keys
And apply it universally.
2020-08-17 14:12:49 +03:00
Alexei Sorokin
27045f03f5 [SESSION] Session ID can be as long as 128 characters 2020-08-17 13:58:19 +03:00
Alexei Sorokin
071baf04fd [NOTICE] Store "url" as TEXT and not VARCHAR(191) 2020-08-17 13:35:16 +03:00
Alexei Sorokin
341e34b766 [DATABASE] Change collation handling
Before now table definitions could define collations only for MariaDB using the
MariaDB's collation names directly.
Now instead definitions get a slightly more abstract collation name syntax, but
only supporting the collations utf8mb4_bin and utf8mb4_unicode_(cs|ci) (wrapped
as utf8_bin, utf8_general_(cs|ci)), because those are the ones that have
practical use for GNU social.

Which also means that on MariaDB the formerly used utf8mb4_general_(cs|ci) have
been superseded by utf8mb4_unicode_(cs|ci), as they are the more modern
replacement.

Introduce collation support on PostgreSQL which results in use of the C (POSIX)
collation as utf8_bin and the und-x-icu collation as utf8_general_cs.
utf8_general_ci is also mapped to und-x-icu, which makes it case-sensitive,
unfortunately.
2020-08-16 23:41:28 +03:00
Alexei Sorokin
5c21816b22 [SEARCH][PostgreSQL] Make LIKE search case-insensitive 2020-08-16 19:05:47 +03:00
Alexei Sorokin
afd18db381 [TwitterBridge] Create Foreign_user before Foreign_link
To keep foreign key constraints intact.
2020-08-13 23:59:40 +03:00
Alexei Sorokin
6c8cd4c9f8 [SEARCH][MariaDB] Change user-facing fulltext search syntax
Now analogous to the simple and safe PostgreSQL's websearch_to_tsquery syntax.
MariaDB's full-text boolean search queries will fail on input such as "@user"
(unquoted) which is particularly noticeable to the user.
2020-08-13 23:44:59 +03:00
Alexei Sorokin
255d395f1d [SEARCH] Exclude message scope 2020-08-13 22:59:41 +03:00
tenma
2f845e98e8 [FFmpeg] Add FFmpeg plugin
FFmpeg plugin serves as a better performant/quality alternative to
resize animated GIFs than the ImageMagick plugin.
2020-08-14 23:32:15 +01:00
tenma
1371e3efb8 [MEDIA] Add WebP support
WebP format is now the default image format for anything that
is not an animated GIF. Image Intervention doesn't support
animated WebPs so we don't convert animated GIFs.

ImageFile:
MediaFile:
default:
- Add WebP support
2020-08-14 19:48:02 +01:00
tenma
8a2c1658a8 [ImageMagick] Remove unnecessary code
ImageMagickPlugin:
- Remove animated thumbnail setting, we'll be able to use FFmpeg for performance
- Remove onFillImageFileMetadata and onCreateFileImageThumbnailSource(), these
  are handled just fine by ImageFile
- Bump minor version number

README:
- Update
2020-08-14 19:48:02 +01:00
Alexei Sorokin
b65c200922 [File] Fix file deletion violating foreign keys 2020-08-13 23:56:31 +03:00
Alexei Sorokin
33caf31237 [RedisCache] Connections should not be shared by daemon threads 2020-08-13 22:51:22 +03:00
Alexei Sorokin
cb7effca05 [Memcached] Do not set persistent connections for daemons 2020-08-13 22:51:22 +03:00
Alexei Sorokin
8745a3e824 [Embed] Fix a query typo in fixup_files.php
Regression introduced in ec86de2bc4
2020-08-13 22:51:22 +03:00
Alexei Sorokin
ac6510d481 [Memcached_DataObject] Thorough check of pivotGetClass arguments 2020-08-12 13:50:39 +03:00
Alexei Sorokin
2109c7b830 [Bookmark] Silence a warning when no tags in BookmarkForm 2020-08-12 13:19:59 +03:00
Alexei Sorokin
629857d3ef [Bookmark] Fix undefined variable "rendered" in Activity options 2020-08-12 13:12:36 +03:00
Alexei Sorokin
60eed202dd [EXTLIB][VALIDATE] Declare everything as static
As was originally intended by the author and is expected.
2020-08-12 12:08:54 +03:00
Alexei Sorokin
14e2621a05 [RSSCloud] Avoid the deprecated in PHP each() function 2020-08-11 19:40:46 +03:00
Alexei Sorokin
99da7963d1 [Managed_DataObject] Remove the "timestamp" type
It is converted to "datetime" in lib/database/schema.php
2020-08-11 18:30:12 +03:00
Alexei Sorokin
2abe910ff5 [RSSCloud] Update schema definition 2020-08-11 18:23:45 +03:00
Alexei Sorokin
15f7941daf [Profile] Allow grantRole to work when role exists 2020-08-11 15:00:57 +03:00
Alexei Sorokin
535b87bb64 [RedisCache][DiskCache] Check if unserialize succeeded 2020-08-10 11:12:31 +03:00
Alexei Sorokin
e63c0d1b03 [TwitterBridge] Check if Notice::$lat and Notice::$lon are defined 2020-08-10 10:35:45 +03:00
Alexei Sorokin
8bc714a2b1 [DATABASE][MariaDB] Always use LONGBLOB for "blob"
"blob" is practically used with the expectation of unlimited length, which is
true with PostgreSQL's bytea, but not with MariaDB's BLOB, which is limited to
64KiB.
So instead use LONGBLOB, which has a maximum of 4GiB, effectively unlimited.
2020-08-10 10:55:59 +03:00
Alexei Sorokin
07b0aa8f52 [DATABASE] Fix remaining misuses of SQL's GROUP BY 2020-08-10 19:29:04 +03:00
Alexei Sorokin
ce665baa88 [Queue_item] There is no "modified" attribute
Fixes a regression introduced in ec86de2bc4
2020-08-10 17:46:30 +03:00
Alexei Sorokin
8c41663175 Revert "[CORE] Avoid the old "reply" relation in inboxnoticestream"
It is needed for mentions.
2020-08-10 17:23:57 +03:00
Alexei Sorokin
7cb10b71bb [RequireValidatedEmail] Only check current user posts
This check made registration impossible when welcomeuser didn't have validation
as well.

And rename the "grandfatherCutoff" option to "exemptBefore".
"Grandfathering" is a relatively obscure term linked to the history of the
United States of America, so replace that with something self-descriptive.
2020-08-09 23:58:25 +03:00
Alexei Sorokin
47cacf5f1a [NOTICES] Restore FullNoticeStream
But only allow a select number of verbs.
This is to display optional subscription notices.
2020-08-09 21:00:14 +03:00
Alexei Sorokin
042e4b070c [EmailAuthentication] Check if e-mail with filter_var 2020-08-09 20:35:31 +03:00
Alexei Sorokin
f84dbb369f [DATABASE] Enable fulltext search by default
Also rename fulltext indices to more fitting names
and move the check from classes into database/schema.php
2020-08-08 18:08:06 +03:00
Alexei Sorokin
34ec165bff [DATABASE][PostgreSQL] Add fulltext search support 2020-08-08 16:56:20 +03:00
Alexei Sorokin
b20c0bdec7 Clean Notice_prefs and Fave_tally when a notice is deleted 2020-08-08 12:22:35 +03:00
t3nma
c527ad0803 [COMPOSER] Add new php-ffmpeg package 2020-08-07 23:42:38 +01:00
Alexei Sorokin
0a6bb5190f [ExtendedProfile] Clean up of missing array indices handling 2020-08-07 11:59:17 +03:00
Alexei Sorokin
cf353f8829 [TwitterBridge] Do not fail on missing notice 2020-08-07 11:42:21 +03:00
Alexei Sorokin
2bd7c021fd [ACTIONS] Fix selftag 2020-08-07 10:20:03 +03:00
Alexei Sorokin
46f788d1eb [UTIL] Fix up common_ensure_session()
Give priority to cookies over GET.

Make sure session ids have only expected characters
(PHP file session handler's limitation).

Replace a mostly useless log warning with a debug message.
2020-08-06 21:54:49 +03:00
Alexei Sorokin
5ea5d30075 [EXCEPTIONS] Inherit the Previous Exception parameter 2020-08-06 20:03:44 +03:00
t3nma
22d650469b [TwitterBridge] Fix issue "Only variables should be assigned by reference"
From the docs: "The new operator returns a reference automatically, so
assigning the result of new by reference is not allowed as of PHP 7.0.0"
2020-08-06 17:25:27 +01:00
Diogo Cordeiro
849ad494d8 [ActivityPub][NOTICE] Process attachments 2020-08-05 18:23:41 +01:00
Diogo Cordeiro
7a2bb38331 [MEDIA] fromUrl now supports using original file name 2020-08-05 17:53:31 +01:00
Diogo Cordeiro
1428ac2cb0 [ActivityPub][NOTICE] Fix variable being wrongly reused 2020-08-05 17:53:31 +01:00
Diogo Cordeiro
efdc7d9ba0 [ActivityPub][INBOX][Delete] Support Delete Actor object being a Tombstone 2020-08-05 17:53:31 +01:00
Diogo Cordeiro
e4e41bb595 [ActivityPub][NOTICE] Fix other federation protocols mention handling 2020-08-04 20:00:55 +01:00
Diogo Cordeiro
379fbb6e5d [ActivityPub][SCRIPTS] Add fix_subscriptions.php 2020-08-04 17:12:01 +01:00
Diogo Cordeiro
09c3236afc [TheFreeNetwork][fix_duplicates.php] Don't die because you couldn't federate an undo follow 2020-08-04 13:03:33 +01:00
Diogo Cordeiro
7d52440461 [TheFreeNetwork][fix_duplicates.php] Small improvements on queries performed 2020-08-04 12:38:51 +01:00
Alexei Sorokin
e206995268 Set HTTP status codes with http_​response_​code() 2020-08-04 14:12:17 +03:00
Alexei Sorokin
ab4120721f [Favorite] Fix "Properly trigger DisfavorNotice on profile deletion"
Calling find() inside delete() is probably not a good idea.
2020-08-04 13:23:31 +03:00
Diogo Cordeiro
a9c365a5eb [VersionBump] 2.0.0alpha0
Ran composer update and locale updater
2020-08-04 05:31:44 +01:00
Diogo Cordeiro
8ad928d48d [TheFreeNetwork] Add Readme
Improve script fix_duplicates.php's comments
2020-08-04 05:10:11 +01:00
t3nma
ebf5efe9f2 [TheFreeNetwork] Add fix_duplicates script 2020-08-04 05:02:06 +01:00
t3nma
c7055341f9 [TheFreeNetwork] Small rewrite to the onStartTFNLookup event 2020-08-04 02:45:32 +01:00
Diogo Cordeiro
34c5be5c42 [MODULES] Make default loading attributes available in global config 2020-08-04 01:36:21 +01:00
t3nma
1675916fda [ActivityPub][QUEUES] Handle Create (AS1 POST) verb properly
Fixes a bug introduced in e504d13120
2020-08-03 18:21:47 +01:00
Alexei Sorokin
a38c608420 [SCHEMA] Better DBMS information fetching
On PostgreSQL:
  - Parse defaults for strings and booleans properly.
  - Parse the "serial" definition type properly.
  - Get information on the "enum" definition type.
  - Re-work getting information about keys/indices.

On MariaDB:
  - Get information about lengths in indices.
  - Get foreign key information separately from the rest as they can have
    colliding names.
2020-08-01 19:05:48 +03:00
Alexei Sorokin
20be1d179a [OpenID][DATABASE] Store UNIX timestamps as BIGINT 2020-07-31 18:40:53 +03:00
Alexei Sorokin
1870f38099 [SCHEMA] Fix a few mistakes 2020-07-31 18:24:12 +03:00
Alexei Sorokin
96eced9845 [BLOCK] Increase type strictness 2020-07-31 16:35:27 +03:00
Alexei Sorokin
92e8c40c55 [DATABASE] Add explicit indices for all foreign keys
This adds a requirement for all definitions that have foreign keys to also
require indices for all source (local) attributes mentioned in foreign keys.

MariaDB/MySQL creates indices for source attributes automatically, so this
serves as a way to get rid of those automatic indices and create clean explicit
ones instead.

In PostgreSQL, most of the time, indices on the source are necessary to
decrease performance penalty of foreign keys (like in MariaDB), but they aren't
created automatically, so this serves to remove that difference between
PostgreSQL and MariaDB.
2020-07-31 16:36:40 +03:00
Alexei Sorokin
0bfa747382 [DATABASE] Fix index identifiers and clean up redundant ones 2020-07-31 16:12:48 +03:00
t3nma
be3c4263b3 [DirectMessage] Update ApiDirectMessageNew action
- Messages are now saved as Notices
2020-07-29 17:50:29 +01:00
t3nma
f00852a619 [DirectMessage] Update ApiDirectMessage action
- getMessages() is now fetching from the Notice table as supposed
- every show{format}* method is properly updated to use Notice objects
- json and xml responses retrieve multi-recipients without compromising
  backwards compatibility
2020-07-28 05:49:37 +01:00
t3nma
83df8848c8 [DirectMessage] Update inboxMessages() to stop fetching replies
This is yet to be supported in the plugin.
2020-07-28 05:48:43 +01:00
t3nma
99183ce4e2 [DirectMessage] PSR12-format 2020-07-28 04:46:10 +01:00
Alexei Sorokin
434ce56e33 [DOCUMENTATION] Adopt PSR-12 and clarify on arrays 2020-07-27 19:19:42 +03:00
Alexei Sorokin
ec86de2bc4 [DATABASE] Update "modified" in Managed_DataObject instead of a DBMS trigger
Instead of relying on the MariaDB's ON UPDATE CURRENT_TIMESTAMP trigger update
"modified" attributes in Managed_DataObject. Every raw query that needs
adjusting is adjusted, as they won't update "modified" automatically anymore.

The main goal behind this change is to fix "modified" updates on PostgreSQL.
2020-07-27 19:10:33 +03:00
Alexei Sorokin
341f3d0ea5 [DATABASE] Fix more incorrect uses of quotation in SQL 2020-07-26 15:28:05 +03:00
Alexei Sorokin
579120df70 [Notice] Fix clearReplies() and clearRepeats() 2020-07-26 15:12:00 +03:00
Alexei Sorokin
63eb323e8b [SHOWSTREAM] Add "noindex" robots meta-tag for silenced profiles 2020-07-26 13:59:37 +03:00
Alexei Sorokin
2861ae2823 [AuthCrypt] Password storage and comparison improvements
Password hashes are now stored in a TEXT attribute, not limited to 199 symbols.
That limitation makes no sense as password hashes are not the kind of
information to be indexed.

Actually replace crypt() with password_verify() for password checking, current
code left password_verify() unused.

Only update passwords when they use a different algorithm from the current
default. Previously "overwrite" meant rehashing every login.

Replace the "argon" boolean option with "algorithm" and "algorithm_options" for
better configurability.
The default remains whichever is default for PHP's password_hash.
2020-07-25 20:16:21 +03:00
Diogo Cordeiro
0b947ce2c7 [AuthCrypt] Update README and fix formatting 2020-07-25 17:42:46 +01:00
Diogo Cordeiro
2222d6d173 [MODULES] Make settings great again
Plugin main class doesn't use this construct despite extending this class.
2020-07-25 17:47:53 +01:00
Alexei Sorokin
33e9b57b78 [Profile][User_group] Fix profile deletion violating foreign keys 2020-07-24 13:09:02 +03:00
Alexei Sorokin
62f4dfdc7a [Favorite] Properly trigger DisfavorNotice on profile deletion 2020-07-24 12:45:30 +03:00
Alexei Sorokin
7e01fd9c38 [DATABASE][MariaDB] Fix index changes with foreign keys enabled 2020-07-23 19:09:41 +03:00
Alexei Sorokin
eefaf7a2b4 [DATABASE][Schema_version] Change the hashing algorithm to SHA3-512 2020-07-23 18:16:56 +03:00
Alexei Sorokin
31dcf99e61 [DATABASE] Make unprefixed schema.php a bit more DBMS-neutral 2020-07-23 18:12:01 +03:00
Diogo Cordeiro
0def5f1dca [ActivityPub][Explorer] More robust exception handler for invalid remote answers 2020-07-23 15:54:40 +01:00
Alexei Sorokin
ac94374f48 [RemoteFollow] Fix location display 2020-07-22 19:49:24 +03:00
Diogo Cordeiro
9f72b6e2c0 [MEDIA] Fix headers when using x-static-delivery 2020-07-22 16:07:52 +01:00
Alexei Sorokin
f9e38c1a8d [LRDD] Fix unhandled bad data in HostMeta, LinkHTML and WebFinger 2020-07-22 01:30:04 +03:00
Diogo Cordeiro
6db56cc949 [ActivityPub][AProfile] Complete strict typing 2020-07-21 23:22:07 +01:00
Alexei Sorokin
7081720ecb [DATABASE] Check SQL boolean values with "IS TRUE"
This way UNKNOWN (NULL) explicitly turns to FALSE when three-valued logic is
reduced to binary.
In pgsqlschema, however, use "IS FALSE" as boolean attributes in pg_index are
non-nullable, there is no outer join and there's no clear preference for NULL
reduction.

Over-complicated constructions in TagCloud queries have been simplified, which
should not affect their performance.

Additionally, in TagCloud's lib/subscriptionspeopleselftagcloudsection.php
a typing mistake in an equi-join of "profile_tag" and "profile_list" on
"tagger" was fixed.
That regression was introduced in f446db8e2a
2020-07-21 18:06:39 +03:00
Diogo Cordeiro
f7ded4d87b [UserFlag] Fix type of onUserRightsCheck 2020-07-21 13:37:36 +01:00
Diogo Cordeiro
67780ca4a9 [UserFlag] Increase strict typing of main file
Run php-cs-fixer
Correct case of class name onDeleteRelated event handlers
2020-07-21 12:43:52 +01:00
Diogo Cordeiro
871f3c4bfe [ActivityPub] Increase type strictness on Explorer 2020-07-21 12:26:23 +01:00
Diogo Cordeiro
395fe8cb10 [ActivityPub] Fix wrong type handling on AProfile:update_profile 2020-07-21 12:02:07 +01:00
Diogo Cordeiro
af936f6f8e [Bookmark] Fix misuse of XMLOutputter
Argument 3 passed to htmloutputter::input() must be of the type string or null, array given, called in /srv/gnusocial/plugins/Bookmark/forms/bookmark.php on line 166
2020-07-17 20:56:51 +01:00
Diogo Cordeiro
5512e95e0a [ExtendedProfile] Fix misuse of XMLOutputter
Argument 1 passed to xmloutputter::text() must be of the type string, null given, called in /srv/gnusocial/plugins/ExtendedProfile/lib/extendedprofilewidget.php on line 556
2020-07-17 20:50:16 +01:00
Hugo Sales
5e14f18c83 [NOTICE][UI] Fix bug: Option to message "Everyone at site" when using private instance 2020-07-16 22:29:59 +00:00
Alexei Sorokin
5adb971d9a [DOCUMENTATION] Adapt the nginx config for avatars located in /file 2020-07-09 18:39:36 +03:00
Alexei Sorokin
f51e5ba19d [CORE] Avoid materialisation in the TaggedProfileNoticeStream query
This is analogous to c862589dcf
2020-07-07 22:41:03 +03:00
Alexei Sorokin
488bddb02a [NOTICE] Update index for verbs in ProfileNoticeStream
After adding a verb condition there, MariaDB now prefers the
("created", "id", "is_local") and ("profile_id", "verb", "created", "id")
indices for that query, even though they are slow for the job.
So replace them with ("is_local", "created", "id") and
("profile_id", "verb", "created", "id") respectively.
Also fix the naming of the ("profile_id", "created", "id") index.
2020-07-07 20:43:08 +03:00
Diogo Cordeiro
3a2ec3ef9c [ActivityPub] Fix bug introduced with 4d171b27
Too few arguments to function Activitypub_notice::create_notice()
2020-07-07 17:57:48 +01:00
Alexei Sorokin
08283f6c54 [RedisCache] Catch string return type from Predis\Client::setex 2020-07-06 20:10:12 +03:00
Alexei Sorokin
f7d3f58318 [CORE] Do not set "confirm_address"."user_id" to 0 by default
That breaks the foreign key constraint, it is better to just have it nullable.
2020-07-06 20:01:16 +03:00
Alexei Sorokin
89e84e9b1b [NOTICES] Revert "We want the profile stream to be as raw as possible!"
There are only three possible visible notice verbs: POST, SHARE and DELETE.
What including all verbs does is it makes limiting (FETCH FIRST) unreliable as
the query will fetch invisible stuff (like favourites) and count it in, but
nothing will be displayed.
NoticeStream only allows POST and SHARE, so this effectively removes tombstones
from the profile page like in 78a111b57d
2020-07-06 19:20:44 +03:00
Alexei Sorokin
9226cce151 [NOTICES] Fix InboxNoticeStream caching
Introduce a new property in CachingNoticeStream for always checking if there
are any new elements in the stream.
It would be extremely hard to blow InboxNoticeStream, so instead the database
hit will still occur, but it is be much faster than starting fresh.

This fixes a regression introduced in 36a55d8436
2020-07-06 18:12:50 +03:00
Diogo Cordeiro
6526bdc824 [TheFreeNetwork] Fix small logic issue regarding StartTFNLookup return 2020-07-05 18:26:49 +01:00
Diogo Cordeiro
1967f46a69 [ActivityPub][SCRIPTS] Make update profiles work with an uri 2020-07-05 17:38:28 +01:00
Diogo Cordeiro
e504d13120 [ActivityPub][QUEUES] Add Like, Undo and Delete 2020-07-05 16:58:05 +01:00
Diogo Cordeiro
2f284f4274 [ActivityPub][INBOX][Delete] Fix misconceptions
References:
- https://socialhub.activitypub.rocks/t/the-delete-activity-and-its-misconceptions/137
- https://socialhub.activitypub.rocks/t/the-update-activity-more-than-caching/260
2020-07-05 16:46:37 +01:00
Diogo Cordeiro
4d171b27a4 [ActivityPub][NOTE] Do not extract actor from attributedTo
There was no checking of attributedTo, actors and referent object IDs to make
sure they exist in the same domain. Therefore, one could spoof messages from
people by doing attributedTo: whoever-i-want-to-spoof
2020-07-05 15:38:12 +01:00
Diogo Cordeiro
fe4a9a6189 [ActivityPub][Ostatus] Fetch avatars in accordance to the new media system 2020-07-05 15:37:52 +01:00
Alexei Sorokin
c862589dcf [CORE] Avoid materialisation in the TagNoticeStream query
The notice.created sort forced the notice_tag by notice join plain to employ
materialisation, which can have a serious performance penalty depending on the
size of the database.
Sort by notice_tag.created instead, which should be exactly the same.
2020-07-01 18:20:44 +03:00
Alexei Sorokin
61765b0e33 [CORE] Avoid the old "reply" relation in inboxnoticestream
All verbs for not visible notices are filtered out, so this should not
break the timeline.
Additionally, filter by profile outside of the derived relation as that shows
better performance in PostgreSQL and MariaDB both.
2020-07-01 17:11:04 +03:00
Alexei Sorokin
78a111b57d Revert "FullNoticeStream selects all verbs"
It appears this was added to display "tombstones" of deleted notices.
However, it has other side-effects and the concept of keeping them visible has
not been adopted by the wider fediverse.
2020-06-30 23:03:41 +03:00
Alexei Sorokin
9a515b9234 [SCHEMA] Improve timestamp storage
Avoid the use of deprecated MariaDB "zero dates" globally. If they're present
as attribute defaults somewhere, they will be replaced with NULL implicitly.
The existing "zero dates" in MariaDB storage will be left intact and this
should not present any issues.

The "timestamp" type in table definitions now corresponds to DATETIME in
MariaDB with "DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP", which
should be close enough to the original behaviour for compatibility purposes.
It is now the recommended type for "modified" attributes, because of the
update trigger on MariaDB. But there is no such trigger implemented on
PostgreSQL as of this moment.
2020-06-29 01:41:46 +03:00
Alexei Sorokin
b924c180ae [DATABASE] Fix MariaDB schema verification 2020-06-28 20:05:11 +03:00
Diogo Cordeiro
737f3eb553 [ActivityPub][HTTPSignatures] Fix verify 2020-06-28 00:58:16 +01:00
Diogo Cordeiro
6e3954f3bb [ActivityPub][Inbox] Signature verification after Actor update would always fail 2020-06-28 00:49:55 +01:00
Diogo Cordeiro
4544f29832 [AVATAR] Ensure this Action stays secure 2020-06-28 00:11:47 +01:00
Hugo Sales
477c357f11 [MEDIA] Move AttachmentAction::sendFile to common_send_file
This fixed the wrong content type and status code returned by the Avatar action
2020-06-27 23:23:10 +01:00
Diogo Cordeiro
7869a7c1b0 [ActivityPub][Inbox] With PHP 7.3 we don't need get_all_headers workaround anymore
Furthermore, it was broken on Apache2 because the actual function
doesn't put the resulting array's key in lowercase.
2020-06-27 20:43:43 +01:00
Alexei Sorokin
edc7159ef6 [Memcached_DataObject] Check if it is possible to sort efficiently 2020-06-27 11:22:19 +03:00
Diogo Cordeiro
1db6943702 [ActivityPub][Inbox] get_all_headers was nginx only 2020-06-26 14:08:47 +01:00
Diogo Cordeiro
e8dff6c4a0 [TESTS] Move AcceptHeader from ActivityPub plugin to Core
Delete temporary ActivityPub tests (they were to be deleted long ago)
2020-06-25 15:50:12 +01:00
Diogo Cordeiro
23ed816035 [ExtendedProfile] Fix XML type bug 2020-06-24 21:44:25 +01:00
Diogo Cordeiro
324b7f38a9 [FORMAT] Run php-cs-fixer on tests/ 2020-06-24 13:55:10 +01:00
Diogo Cordeiro
aa7aff3f6b [TESTS] Fix CommandInterpreterTest
Also corrected a bad refactoring that affected Xmpp plugin test
2020-06-24 13:54:38 +01:00
Diogo Cordeiro
236929a166 [PEAR] I'm tired of this issue still popping up, this seems to silence it 2020-06-24 13:08:58 +01:00
Diogo Cordeiro
953e243639 [UI] Make neo-quitter default theme 2020-06-21 00:34:55 +01:00
Diogo Cordeiro
338d53c982 [XML] Inscrease types strictness 2020-06-21 00:34:54 +01:00
Diogo Cordeiro
37ebcc509b [AVATAR] Temporary ImageFile wasn't 2020-06-21 00:34:27 +01:00
Diogo Cordeiro
f9be6f9a85 [AVATAR] Try to delete tmp avatar if something goes wrong during the process 2020-06-20 14:47:35 +01:00
Diogo Cordeiro
2cc2b5b856 [MEDIA] ImageFile fromUpload method wasn't ensuring uploaded file was an image 2020-06-20 14:47:33 +01:00
Alexei Sorokin
194976135f [DATABASE] Some query improvements
Make common_sql_weight employ standard SQL functions for the timestamp
difference in seconds.
Also replace UTC_TIMESTAMP in the MariaDB-specific part with CURRENT_TIMESTAMP
as it is the only occurence and GNU social sets UTC as a default timezone.

In a delete_orphan_files.php script simplify the main query considerably.

In clean_profiles.php stop using COUNT as if it is ANY, that is unnecessary
punishment for the database. Instead implement the anti-join with a
left outer join.

In Autocomplete and Activitypub_profile use joins instead of a WHERE OR
anti-pattern for the semi-joins.

In lib/ui/galleryaction.php replace a CROSS JOIN with an INNER JOIN.

In actions/sup.php remove a redundant subquery: WHERE is applied before
grouping either way.
2020-06-10 16:52:00 +03:00
Alexei Sorokin
ef17f3ea7d [CORE][DATABASE] Another approach to semi-join in the inboxnoticestream query
Compared to the solution with INNER JOIN this seems to have better performance
as there is no need to deduplicate the subquery result before use.
2020-06-10 14:21:47 +03:00
Alexei Sorokin
0eec6fcfb6 [DATABASE] Replace NOW() with CURRENT_TIMESTAMP 2020-06-09 20:26:06 +03:00
Alexei Sorokin
09a772419a [DATABASE] Use "<>" as an SQL non-equality sign in more cases
A follow-up to commit 644b417f6c
2020-06-08 18:31:22 +03:00
Alexei Sorokin
6c035d01d4 [DATABASE] Start transactions with START TRANSACTION
"BEGIN" is non-standard and unnecessary.
2020-06-08 12:25:01 +03:00
susdiv
97bddc4537 [Autocomplete] Fix postgres incompatible query in AutocompleteAction 2020-06-05 19:14:37 +00:00
susdiv
684675bd84 [SCRIPTS] Fix postgres incompatible query in clean_profiles.php 2020-06-05 17:57:22 +00:00
susdiv
b8c0fa9fa0 [ActivityPub] Fix Postgres incompatible query in Following and Followed collection 2020-06-05 17:48:21 +00:00
Diogo Cordeiro
9e7794cd66 Merge branch 'nightly' of rainydaysavings/gnu-social into nightly 2020-06-03 00:08:53 +00:00
rainydaysavings
92ad44abf9 [THEME][neo-quitter] Added icon for Network in navbar 2020-06-03 00:59:22 +01:00
Hugo Sales
7e83ddf80e [FIX] Fix 'Trying to access array offset on value of type null' in AntiBrutePlugin and SimpleCaptchaPlugin when using scripts 2020-05-24 16:55:37 +00:00
tenma
a9be720f09 [OStatus] Remove TFN's deprecated Census event and fix small typo in the code 2020-05-09 11:50:26 +01:00
tenma
d7906f113e [ActivityPub] Remove TFN's deprecated Census event 2020-05-09 11:50:26 +01:00
tenma
01dcaefcfb [TheFreeNetwork] Use config + module settings for initialization and online lookup
The Census event is now replaced with module settings for populating the
protocols array. With this we can shutdown some plugins and still make
them be checked by TFN.

The performance:high config is now added when deciding whether or not to
do online lookup after the offline lookup fails.

default:
- Add default values for the TFN protocol setting

EVENTS:
- Remove Cencus event

TheFreeNetworkModule
- Remove Census event handler, update protocols array to use module's settings
- Use performance:high config when deciding to do online lookup
2020-05-09 11:50:26 +01:00
tenma
cfba91ea43 [OStatus] Add TheFreeNetwork module's support in handling profile insertion
Ostatus_profile:
- Update createActivityObjectProfile to trigger TFN's assistance in inserting the profile
2020-05-09 11:50:26 +01:00
tenma
134b6f6478 [ActivityPub] Add TheFreeNetwork module's support in handling profile insertion
Activitypub_profile:
- Update do_insert to trigger TFN's assistance in inserting the profile

explorer:
- Use the new LRDD's method for grabbing profile aliases
2020-05-09 11:50:25 +01:00
tenma
64104cb182 [TheFreeNetwork] Handle new StartTFNLookup and EndTFNLookup events
EVENTS:
- describe new events

TheFreeNetworkModule:
- add event handlers and necessary auxiliary methods
- minor comment updates
2020-05-09 11:50:25 +01:00
tenma
9aedcc7997 [OStatus] Update salmonaction to use the new LRDD's method for grabbing aliases 2020-05-09 11:50:25 +01:00
tenma
35547e28ea [LRDD] Add a new method for grabing profile aliases 2020-05-09 11:50:25 +01:00
tenma
c6543e1f95 [ActivityPub] Autofix profile URIs through alias discovering
Activitypub_profile:
- Add updateUri method

explorer:
- Add grab_aliases method
- Update grab_local_user's online course to grab and test aliases
2020-05-09 11:50:25 +01:00
Alexei Sorokin
2183875e9e [UI] Fix group member pages showing up twice 2020-05-05 16:49:21 +03:00
Alexei Sorokin
e5ee069f4a [UI] Order groups in join descending order in profiles 2020-05-05 16:25:02 +03:00
Hugo Sales
6c844315aa [CORE] Fix 'Array and string offset access syntax with curly braces is deprecated' in AuthCryptModule and DirectionDetectorPlugin 2020-05-04 10:47:23 +00:00
Alexei Sorokin
872bb1388d [Nodeinfo] Count active users for full days and without silenced 2020-04-17 18:13:05 +03:00
Alexei Sorokin
42aa255152 [CORE] Re-format the inboxnoticestream query 2020-04-08 15:25:30 +03:00
Diogo Cordeiro
e58188d136 [UI] Small improvement on attachment's visual 2020-04-07 13:28:34 +01:00
Diogo Cordeiro
bb32c0af3b [SensitiveContent] Fix plugin settings
Also reformatted the code and minor bug fixed it
2020-04-07 13:28:29 +01:00
nee
63fd2c7037 [SensitiveContent] Add option to activate for not-logged-in visitors
Remove redundant setting retrival code.

An example config.php entry to activate the new config:
$config['site']['sensitivecontent']['hideforvisitors'] = true;
2020-04-07 02:59:35 +01:00
nee
520a2ba202 [SensitiveContent] Don't crash in GNU social classic
When an attachment has no thumbnail (for example when it's a video).
2020-04-07 02:59:30 +01:00
Hugo Sales
13e8445083 [SensitiveContent] Fix bug where having this plugin activated would not size thumbnails correctly 2020-04-07 02:59:24 +01:00
Hugo Sales
d1c70cb13b [CORE] Make avatars be served with the same mechanism as attachments 2020-04-06 21:14:11 +00:00
Diogo Cordeiro
6898cff623 [PLUGINS] Remove VideoThumbnails not useful anymore 2020-04-03 12:20:27 +01:00
Diogo Cordeiro
f4558e3c41 [ActivityPub] Fix profile url handling 2020-03-28 03:16:24 +00:00
tenma
d24075b1c5 [INSTALL] Allow the setup of sslproxy during install time
install.php:
installer.php:
- add option field and handle logic

display.css:
- hardcode ssl's label margin-top value so all options are correctly displayed
2020-03-15 21:37:37 +00:00
tenma
a8c2a9da3a [DOCUMENTATION] Add further notes to the nginx sample config 2020-03-12 18:03:48 +00:00
tenma
8041df7d41 [DATABASE] Fix deprecated call to implode() 2020-03-12 17:44:50 +00:00
Diogo Cordeiro
073a181778 [ActivityPub] Fix undefined tag index 'type' in Activitypub_notice 2020-02-14 17:25:26 +00:00
Diogo Cordeiro
bec6fdc66a [NOTICES] Add data-nosnippet attribute for notices by remote profiles 2020-01-09 19:49:49 +00:00
Diogo Cordeiro
6833c9f1c2 [SHOWSTREAM] Add robots meta-tag for remote profiles 2020-01-09 17:02:26 +00:00
Diogo Cordeiro
18ade30185 [FORMAT] Ran php-cs-fixer on the handlers of notice items and streams
This was to keep the following two commits readable
- actions/showstream.php
- actions/userbyid.php
- lib/modules/ActivityHandlerModule.php
- lib/modules/ActivityHandlerPlugin.php
- lib/notices/conversationnoticestream.php
- lib/notices/noticelistitem.php
- lib/notices/noticestream.php
- lib/notices/threadednoticelistitem.php
2020-01-09 21:41:34 +00:00
Alexei Sorokin
e7ab305335 [CORE] Use monotonic time via hrtime() where applicable
The realtime clock is not reliable when calculating elapsed time.
2020-01-07 19:48:13 +03:00
Alexei Sorokin
110d3a453a [Embed][CORE] Validate the hexadecimal for hex2bin properly 2020-01-07 17:30:18 +03:00
Alexei Sorokin
f5aeab39b4 [PEAR DB_DataObject] Make static methods in Cast actually static 2020-01-07 17:16:07 +03:00
Diogo Cordeiro
e7738895ce [DOCUMENTATION] Updated TODO and branches info 2019-12-23 15:39:26 +00:00
Diogo Cordeiro
60446dfc20 [CORE] Better queues defaults 2019-12-11 02:23:37 +00:00
Diogo Cordeiro
dc211c9c44 [ActivityPub][Postman] Fix not sending notices to self 2019-12-11 01:30:25 +00:00
Diogo Cordeiro
27babac6dc [Ostatus] Partially revert 69add504e6
updateuris isn't needed after alll, we should solve this with TFNM and existing infrastructure.
2019-12-11 01:30:15 +00:00
Diogo Cordeiro
3e2b7cddc8 [ActivityPub][RSA] Revision, increase type scrictness and improve docs 2019-12-10 23:51:40 +00:00
Diogo Cordeiro
80ba2b3ccc [ActivityPub] Properly handle Actor URIs by using events correctly
This should fix nulls on explorer lookups inputed by postman after generate_followers/getSubscribers, that I think were caused by calling common_profile_uri that, curiously, only handles local profiles
2019-12-10 23:50:56 +00:00
Diogo Cordeiro
b730582336 [CORE] Add GNUSOCIAL_ENGINE_REPO_URL and increase usage of GNUSOCIAL_ENGINE_URL 2019-11-21 00:21:22 +00:00
Alexei Sorokin
1b429dd2e5 [API] Show a nicer no such user error on statusnet/groups/list_all 2019-11-16 22:12:42 +03:00
Alexei Sorokin
448404e45c [SCRIPTS] Fix resend_confirm_address.php
Fix a regression from 6ec72b2978,
check if an address is set when using --email.
2019-11-16 21:22:46 +03:00
Alexei Sorokin
562d84c375 [Xmpp] Adjust type declarations for changes in XMPPHP 2019-11-16 20:44:18 +03:00
Diogo Cordeiro
f09e3362aa [COMPOSER] update 2019-11-16 16:51:01 +00:00
Diogo Cordeiro
51b5b1c08c [ActivityPub][RSA] Fix types of generate_keys 2019-11-16 15:32:49 +00:00
Diogo Cordeiro
ca2dde9a41 [ExtendedProfile] Fix updates and allow to delete values 2019-11-03 19:49:10 +03:00
Alexei Sorokin
6674d1ed0f [NodeInfo][DATABASE] Adjust indices of the "notice" and "user" tables
On big databases these queries from the Nodeinfo plugin choked up:

SELECT profile_id FROM notice
  WHERE notice.created >= (CURRENT_DATE - INTERVAL '180' DAY)
  AND notice.is_local = 1;
SELECT id FROM "user"
  WHERE "user".created >= (CURRENT_DATE - INTERVAL '180' DAY);
2019-11-03 18:57:03 +03:00
Diogo Cordeiro
2a10dffff8 [UI] Fix a small typo 2019-11-03 15:53:11 +00:00
Diogo Cordeiro
e0b17fc97d [REALTIME] Reviewed both the superclass and its dist plugins 2019-11-03 15:37:49 +00:00
Alexei Sorokin
52800c3a65 [DATABASE] Remove profile_tag_tag_fkey
profile_list.tag is not supposed to be unique,
this also reverts the addition of profile_list_tag_key.
2019-11-02 14:32:48 +03:00
Alexei Sorokin
9124617055 [Xmpp] Latin-1 space characters are not forbidden for XMPP resources
Also use mb_strlen() with the 8bit encoding to count octets, strlen() is not as
reliable (mbstring.func_overload).
2019-11-02 13:54:26 +03:00
Alexei Sorokin
b312712d1b [Xmpp] Use UnexpectedValueException in splitJid, a bit narrower 2019-11-02 13:29:00 +03:00
Alexei Sorokin
5bc1b8695e [DATABASE] Disable 'NULL' strings evaluation as SQL NULLs
Use $object->sqlValue('NULL') (identical to DataObject_Cast'ing) instead and
fix related issues like (email|sms)settings considering these NULLs as a
false positive for the E-Mail address still being set when it's been removed.

There could also be security implications to the now-disabled approach of
considering 'NULL' strings as SQL NULLs.
2019-11-02 12:21:43 +03:00
Diogo Cordeiro
d921f3dadb [ActivityPub] New URI system 2019-11-10 17:47:51 +00:00
Diogo Cordeiro
c154712012 [PEAR DB_DataObject] Removed DB_DATAOBJECT_NO_OVERLOAD as we don't have support for either PHP 4 or 5 2019-11-03 00:43:21 +00:00
tenma
3634af3fdc [TheFreeNetwork] First code: Module class and census event 2019-11-03 00:43:21 +00:00
tenma
1df9ec9f0f [SCRIPTS] Add updateuris script
To fix user URIs to their non-fancy version
2019-11-03 00:43:21 +00:00
tenma
ae54a94d41 [CORE] Update common_user_uri
To be consistent between federated-protocols and maintain non-fancy URIs
2019-11-03 00:43:21 +00:00
tenma
69add504e6 [OStatus] Add script for profile deduplication and URI fixing 2019-11-03 00:43:21 +00:00
tenma
a0d30b6872 [ActivityPub] Fix some small known problems
ActivityPubPlugin:
- Rework onProfileDeleteRelated to account for the tables _rsa and _pending_follow_requests
- Update onEndShowAccountProfileBlock to stop creating the ap_profile if it doesn't exist (we'll handle this in a different manner)

Activitypub_profile:
- Remove unnecessary code from from_profile method and add return type information

Explorer:
- Update travel_collection to call itself instead of _lookup, that was wrong
2019-11-03 00:43:21 +00:00
Alexei Sorokin
a06b33be66 [AnonymousFave][DATABASE] Set the created timestamp on INSERT 2019-11-01 16:09:09 +03:00
Alexei Sorokin
fe3e33e702 [DAEMONS][TwitterBridge] Set PUBLICDIR 2019-11-01 15:27:36 +03:00
Alexei Sorokin
3f56459734 [COMPOSER] Remove some pre-composer remnants from the code 2019-11-01 14:19:42 +03:00
Alexei Sorokin
4903241e4b [DOCUMENTATION][NGINX conf] snippets/fastcgi-php.conf is Debian-specific 2019-11-01 08:52:21 +03:00
Alexei Sorokin
85be003cf5 [Embed][CORE] hex2bin should always get an even amount of symbols 2019-11-01 08:29:52 +03:00
tenma
bddc1c0f9d [ActivityPub] Fix successive "Cannot use object of type stdClass as array" errors in the postman 2019-11-01 02:23:39 +00:00
tenma
01f6d83b86 [MODULES] Fix VERSION constant to MODULE_VERSION in various modules 2019-10-30 23:52:14 +00:00
Diogo Cordeiro
aa994ee4fb [CORE] Allow to force non-fancy URLs
Essential to allow toggling fancy urls later. In some cases it is
critical to keep the URL an unique URI.
2019-10-27 17:40:37 +00:00
Diogo Cordeiro
d058a70557 [MEDIA] Simplify Attachment actions 2019-10-19 02:57:32 +01:00
Diogo Cordeiro
7298468df7 [FILE] Fix Return value of File::getFileOrThumbnailSize() must be of the type int, null returned 2019-10-19 01:16:37 +01:00
Diogo Cordeiro
63caa5044d [LIB_REFACTOR] Fix minor issues 2019-10-19 00:51:52 +01:00
tenma
2ae93dbec6 [ActivityPub] Revert usage of bitwise-operator & in the inbox_handler class. 2019-10-17 20:25:00 +01:00
Diogo Cordeiro
b434bead2c [ActivityPub] The protocol allows content to be null, GNU social doesn't, we'll reject silentiously
Reported by kaniini
2019-10-11 19:09:12 +01:00
Diogo Cordeiro
6284b155b8 [ActivityPub] attributedTo itself is not required, if not present then it should be inferred from the actor
Reported by kaniini
2019-10-11 17:51:20 +01:00
Diogo Cordeiro
b12c2d17d5 [ActivityPub] Fix security issue concerning remote profile deletes
Reported by kaniini
2019-10-11 17:41:43 +01:00
Diogo Cordeiro
5fb1e26a4c [ActivityPub] Inbox Handler: Remove old guzzle import
Improve exception information in doc blocks
2019-10-11 17:18:50 +01:00
Diogo Cordeiro
6423750250 [ActivityPub] Slightly increase robustness on exception handling
Also ported Activitypub_rsa to PHP7
Minor indentation fixes
2019-10-11 17:08:41 +01:00
Diogo Cordeiro
d9b5ef1cee [ActivityPub] Consistent headers in explorer requests
Minor indentation fixes
2019-10-11 16:00:14 +01:00
Miguel Dantas
f1717bde51 Fix 'Call to a member function getPayload() on null'
Trying to enable the RedisCache with the latest nightly, getting this with the daemon:

sep 25 11:40:18 friedrich startdaemons.sh[21428]: PHP Fatal error:  Uncaught Error: Call to a member function getPayload() on null in /var/www/social/plugins/RedisCache/RedisCachePlugin.php:96
sep 25 11:40:18 friedrich startdaemons.sh[21428]: Stack trace:
sep 25 11:40:18 friedrich startdaemons.sh[21428]: #0 /var/www/social/lib/util/event.php(89): RedisCachePlugin->onStartCacheSet('gnusocial:herds...', Object(HubSub), NULL, 86400, false)
sep 25 11:40:18 friedrich startdaemons.sh[21428]: #1 /var/www/social/lib/cache/cache.php(202): Event::handle('StartCacheSet', Array)
sep 25 11:40:18 friedrich startdaemons.sh[21428]: #2 /var/www/social/classes/Memcached_DataObject.php(520): Cache->set('gnusocial:herds...', Object(HubSub))
sep 25 11:40:18 friedrich startdaemons.sh[21428]: #3 /var/www/social/classes/Memcached_DataObject.php(52): Memcached_DataObject->encache()
sep 25 11:40:18 friedrich startdaemons.sh[21428]: #4 /var/www/social/classes/Managed_DataObject.php(50): Memcached_DataObject::getClassKV('HubSub', 'hashkey', 'a38b9dc516371af...')
sep 25 11:40:18 friedrich startdaemons.sh[21428]: #5 /var/www/social/plugins/OStatus/classes/HubSub.php(47): Managed_DataObject::getKV('hashkey', 'a38b9dc516371af...')
sep 25 11:40:18 friedrich startdaemons.sh[21428]: #6 /var/www/social/plugins/OStatus/lib/hubprepqueuehandler.php(68): HubSub::getByHashkey('https://herds.e...', 'https://raki.so...')
sep 25 11:40:18 friedrich startdaemons.sh[21428]: #7 /var/www/social/plugins/RedisQueue/classes/RedisQueueManager.php(58): HubPrepQueueHandl in /var/www/social/plugins/RedisCache/RedisCachePlugin.php on line 96
Sign in to j
2019-09-26 11:29:31 +01:00
Miguel Dantas
c6f4f40bba [Embed][CORE] Fixes 'Invalid Filename' on Embed. Regex didn't get updated 2019-09-26 11:29:31 +01:00
Alexei Sorokin
65f1b1e1e3 Fix minor git merge resolving issues 2019-09-18 17:43:00 +03:00
Alexei Sorokin
ad91ef66bd [SCRIPTS] Set PUBLICDIR in plugin scripts as well 2019-09-18 17:15:00 +03:00
Alexei Sorokin
6bfa593988 [DAEMONS] Move resetDb to the Daemon class
As it is used inside the Daemon class now, it should always be available.
2019-09-13 22:08:42 +03:00
Diogo Cordeiro
3ea580b537 [ActivityPub] Add missing parenthesis in class instantiation
Fixed some issues related to thrown exceptions in the doblocks; also boolean -> bool
2019-09-13 18:58:41 +01:00
Alexei Sorokin
87b0b493eb [ActivityPub] Fix an unhandled error in onStartGetProfileFromURI 2019-09-13 20:55:23 +03:00
Diogo Cordeiro
4eb4a2de00 [ActivityPub] Fix some bugs with onStartNoticeSearch
Refactored Activitypub_profile::ensure_web_finger to Activitypub_profile::ensure_webfinger
Do not throw exceptions in the handling of this event because we don't
want to stop the regular search just because we were unable to find
ActivityPub actors or notes.
2019-09-13 18:10:20 +01:00
Alexei Sorokin
1f2f57b03b [CORE] Fix logging of very early failures 2019-09-13 12:11:43 +03:00
Alexei Sorokin
4afaad3df5 [DATABASE][MariaDB] Properly account for foreign keys 2019-09-13 10:34:48 +03:00
Diogo Cordeiro
c3ba2e0f94 [BugFix] Plugins ExtendedProfile and OverwriteThemeBackground - admin is identical to system path names. 2019-09-12 23:18:50 +01:00
Alexei Sorokin
693c3168da [OStatus] The unsubscribe state also needs a label 2019-09-12 14:19:21 +03:00
Alexei Sorokin
8f309bc768 Merge branch 'pgsql_support' into nightly 2019-09-12 12:01:50 +03:00
Alexei Sorokin
1a0d6a90c2 [INSTALL] Fix lib/util/installer.php import path 2019-09-12 11:52:04 +03:00
Diogo Cordeiro
7f2019b4af [MODULES] Make disable in admin panel effective 2019-09-12 04:50:46 +01:00
Alexei Sorokin
ee7f0a2016 [DATABASE] Re-introduce PostgreSQL support 2019-09-11 14:14:40 +03:00
Alexei Sorokin
644b417f6c [DATABASE] Use "<>" as an SQL non-equality sign
"!=" is not SQL compliant.
2019-09-11 13:27:36 +03:00
Alexei Sorokin
471576d6e8 [DATABASE] Columns not in GROUP BY must not be queried 2019-09-11 13:12:41 +03:00
Alexei Sorokin
7ee8aa7838 [DATABASE] Re-introduce the enum type abstraction 2019-09-11 12:48:28 +03:00
Alexei Sorokin
af63e9a7ad [DATABASE] Set all primary keys as "not null" explicitly 2019-09-11 12:27:40 +03:00
Alexei Sorokin
95c7344557 [DATABASE] Various table schema related fixes 2019-09-11 12:07:54 +03:00
Alexei Sorokin
0c936e54ba [DATABASE] Re-order tables to be created
Foreign keys need to be created after the respective tables are already in
place. This order makes sure this is the case.
2019-09-11 11:56:36 +03:00
Alexei Sorokin
62b90c29db [DATABASE] Introduce a bool type in schema
PostgreSQL has a clear distinction between integers and booleans, so it makes
sense to draw a clear line.
2019-09-11 11:25:39 +03:00
Alexei Sorokin
6911b499d3 [DATABASE] Consistently use the "LIMIT $limit OFFSET $offset" syntax
The "LIMIT $offset, $limit" syntax is only supported by MySQL and MariaDB.
2019-09-11 10:12:49 +03:00
Alexei Sorokin
44f4c9374d [DATABASE] Use time intervals in a SQL standard compliant way 2019-09-11 09:58:13 +03:00
Alexei Sorokin
11dabbe44d [DATABASE] Only use single quotation marks for SQL strings
Double quotation marks are only used for identifiers in the SQL standard.
2019-09-11 09:46:30 +03:00
Alexei Sorokin
0a5a3845db [DATABASE] Set NULL in DB_DataObject in a more reliable manner
Also stop assuming that FeedSub::sub_state (enum) and FeedSub::sub_end
(datetime) can possibly be set to an empty string.
2019-09-11 08:32:19 +03:00
Alexei Sorokin
5b797328f2 [DATABASE] Always quote identifiers
The code used to operate under the assumption that MariaDB doesn't support
quoting identifiers. Not only is that not exactly true, but MariaDB has
reserved keywords that cannot be used as table or column names unquoted.
2019-09-11 08:15:16 +03:00
Alexei Sorokin
b89f1ad7d8 [CORE] Another inboxnoticestream improvement 2019-09-10 22:25:45 +03:00
Alexei Sorokin
b0104d9992 [DAEMONS] Switch daemons to double-forking for daemonisation 2019-09-10 21:14:27 +03:00
Alexei Sorokin
9d8f4c774f [DAEMONS] Properly disconnect daemons from the database 2019-09-10 20:25:28 +03:00
Diogo Cordeiro
8b7a22ecd9 Merge branch 'nightly' of biodantas/gnu-social into nightly 2019-09-10 17:11:00 +00:00
Miguel Dantas
a4e6db8d76 [OpportunisticQM] Revamped plugin to be able to use other poll based queuemanagers, no just the DB 2019-09-05 01:39:00 +02:00
Miguel Dantas
78506d5249 [StompQueue] Changed StompQueueManager to use polling rather than sockets 2019-09-05 01:39:00 +02:00
Miguel Dantas
6747b18b75 [PLUGINS] Added UnQueue, a new default plugin which does all actions immediately 2019-09-05 01:39:00 +02:00
Miguel Dantas
544f13c52a [PLUGINS] Added DBQueue plugin 2019-09-05 01:38:59 +02:00
Miguel Dantas
4644f6e96b [PLUGINS] Added StompQueue plugin, based on the implementation in lib/queue/stompqueuemanager. Updated to new STOMP library version. Dropped liberalstomp.php and stompqueuemanager.php 2019-09-05 01:38:40 +02:00
Miguel Dantas
a3b228399b [PLUGINS] Added RedisQueue 2019-09-03 14:01:27 +01:00
Miguel Dantas
100a557c7c [CORE][AUTOLOAD] Fix class OAuthRequest not found
Issue description as reported by aab:

2019-08-28 17:34:48 LOG_ERR: [khp.ignorelist.com:61055.f5f7f51c GET /api/statuses/show/178372.atom] ServerErrorAction: 500 Class 'OAuthRequest' not found
2019-08-28 17:39:50 LOG_ERR: [khp.ignorelist.com:65390.4483ff85 GET /api/statusnet/conversation/104672.rss] Handled serverError (500) but cannot output into desired format ('rss'): 'Class \'OAuthRequest\' not found'
2019-08-28 17:39:50 LOG_ERR: [khp.ignorelist.com:65390.4483ff85 GET /api/statusnet/conversation/104672.rss] ServerErrorAction: 500 Class 'OAuthRequest' not found
2019-08-28 17:40:49 LOG_ERR: [khp.ignorelist.com:65390.4c745f68 GET /api/statuses/show/18132.atom] Handled serverError (500) but cannot output into desired format ('atom'): 'Class \'OAuthRequest\' not found'
2019-08-28 17:40:49 LOG_ERR: [khp.ignorelist.com:65390.4c745f68 GET /api/statuses/show/18132.atom] ServerErrorAction: 500 Class 'OAuthRequest' not found
2019-08-28 17:47:41 LOG_ERR: [khp.ignorelist.com:65390.42ee9fd4 GET /api/statusnet/conversation/133023.as] Handled serverError (500) but cannot output into desired format ('as'): 'Class \'OAuthRequest\' not found'
2019-09-03 03:33:14 +01:00
Miguel Dantas
6acc75ccff [FRAMEWORK][AUTOLOAD] Fix autoloads 2019-09-03 03:33:14 +01:00
Miguel Dantas
b41f9620fa [LIB_REFACTOR] Fix requires 2019-09-03 03:33:13 +01:00
Miguel Dantas
58bde08425 [LIB_REFACTOR] Moving files into separate semantic categories 2019-09-03 03:33:13 +01:00
Miguel Dantas
7d6c6edab3 [RedisCache] Fix call to getPayload on int. The library is badly documented, but seems to return the TTL instead of the normal redis response
Issue description as reported by aab:

About one day after enabling redis plugin:

PHP Fatal error:  Uncaught Error: Call to a member function getPayload() on int in /var/www/html/plugins/RedisCache/RedisCachePlugin.php:96
Stack trace:
0 /var/www/html/lib/event.php(89): RedisCachePlugin->onStartCacheSet('gnusocial:gatea...', Object(Queue_item), NULL, 86400, false)
1 /var/www/html/lib/cache.php(202): Event::handle('StartCacheSet', Array)
2 /var/www/html/classes/Memcached_DataObject.php(496): Cache->set('gnusocial:gatea...', Object(Queue_item))
3 /var/www/html/classes/Memcached_DataObject.php(416): Memcached_DataObject->encache()
4 /var/www/html/classes/Managed_DataObject.php(620): Memcached_DataObject->update(Object(Queue_item))
5 /var/www/html/classes/Queue_item.php(74): Managed_DataObject->update(Object(Queue_item))
6 /var/www/html/lib/dbqueuemanager.php(75): Queue_item::top(Array, Array)
7 /var/www/html/lib/iomaster.php(287): DBQueueManager->poll()
8 /var/www/html/lib/iomaster.php(161): IoMaster->poll()
9 /var/www/html/scripts/queuedaemon.php(112): IoMaster->service()
10 /var/www/html/lib/spawni in /var/www/html/plugins/RedisCache/RedisCachePlugin.php on line 96
2019-09-03 03:31:59 +01:00
Miguel Dantas
d209964718 [Memcached] Fix call to undefined method close
Issue description as reported by aab:

Memcached config in config.php:

    addPlugin('Memcached', [ 'servers' => ['127.0.0.1', 11211],
                             'defaultExpiry' => 86400 // 24h
                           ]);

Memcached and php-memchached installed.

The error appears when executing startdaemons.

Log:

    PHP Fatal error:  Uncaught Error: Call to undefined method Memcached::close() in /var/www/html/plugins/Memcached/MemcachedPlugin.php:202
    Stack trace:
    #0 /var/www/html/lib/event.php(89): MemcachedPlugin->onStartCacheReconnect(false)
    #1 /var/www/html/lib/cache.php(273): Event::handle('StartCacheRecon...', Array)
    #2 /var/www/html/lib/spawningdaemon.php(209): Cache->reconnect()
    #3 /var/www/html/lib/spawningdaemon.php(188): SpawningDaemon->resetDb()
    #4 /var/www/html/lib/spawningdaemon.php(118): SpawningDaemon->initAndRunChild(3)
    #5 /var/www/html/lib/daemon.php(168): SpawningDaemon->run()
    #6 /var/www/html/scripts/queuedaemon.php(186): Daemon->runOnce()
    #7 {main}
      thrown in /var/www/html/plugins/Memcached/MemcachedPlugin.php on line 202
2019-09-03 03:30:07 +01:00
Miguel Dantas
c03f659efb [Embed] Fix use of undefined img_data
Got error 'PHP message: PHP Notice: Undefined variable: img_data in /var/www/html/plugins/Embed/EmbedPlugin.php on line 544'
2019-09-03 03:29:32 +01:00
tenma
2e66cbeb60 [CORE] Fix undefined offset warnings in different files
This problem was presentend in the following issue:
https://notabug.org/diogo/gnu-social/issues/60

AcceptHeader/util:
- Perform isset before using the required array values
2019-09-03 03:26:35 +01:00
tenma
19409cb999 [ActivityPub] Add support fox search-box profile/notice grabbing
NoticeSearchAction:
- Add new event before finding query matches

ActivityPubPlugin:
- Subscribe new searchNotice event
- Bump minor version number

Activitypub_explorer:
- Update lookup to make remote-grabbing optional
2019-09-03 03:26:35 +01:00
tenma
c06182c38f [ActivityPub] Handle DELETE-Person activity
ActivityPubPlugin:
- update grab_notice_from_url to make online grab optional
- subscribe events of user and profile deletion
- bump minor version number

Activitypub_inbox_handler:
- separate handle_delete for delete-note and delete-person

Activitypub_postman:
- add delete-person logic

Activitypub_delete:
- update validation method to check for the "Person" type
- update to_array method to target the activity
2019-09-03 03:26:35 +01:00
Miguel Dantas
f79cd8cee3 [CORE] Fix small bug where Notice was sending a JSON representation to the queue, instead of sending itself 2019-09-03 03:26:35 +01:00
tenma
c130739de0 [AP] Fix subscription events
Both StartSubscribe and StartUnsubscribe had a wrong initial if-condition.
Furthermore, this events were calling Activitypub_profile::from_profile()
which is wrong because it creates the Activitypub_profile object when
the goal is only to check if it exists already.
2019-09-03 03:26:35 +01:00
tenma
1a4a1583d5 [AP] Subscribe RemoteFollow plugin events for allowing following with the remote-follow button 2019-09-03 03:26:35 +01:00
tenma
3633ca04eb [OStatus] Port remote-follow to the RemoteFollow plugin
OStatusPlugin:
- Stop adding the remote-follow button
- Subscribe to required RemoteFollow plugin events
- Drop main/ostatussub route and update urls to the main/RemoteFollowSub route
- Bump plugin minor version number

actions/ostatusgroup,
actions/ostatuspeopletag:
- Update urls to the main/RemoteFollowSub route

lib/util:
- Port required functions from OStatusSubAction and adapt to be used with the new events
2019-09-03 03:26:35 +01:00
tenma
e61c0c45aa [RemoteFollow] Initial work in the RemoteFollow plugin
lib/default.php
- Add RemoteFollow to the list of default plugins

RemoteFollowPlugin:
- Subscribe events to add the remote-follow button

RemoteFollowInitAction:
- Handles the remote-follow form and getting the redirection url for follow completion

RemoteFollowSubAction:
- Handles the remote profile pulling and actual following
2019-09-03 03:26:35 +01:00
Miguel Dantas
6d81848f25 [URLMAPPER] Fix small bug in URLMapper: a dynamic route might not exist even if a static one does 2019-09-03 03:26:35 +01:00
Miguel Dantas
10b3b343dd [DirectMessage] Fixed use of incorrect type which prevented posting notices with only one word 2019-09-03 03:26:35 +01:00
tenma
f6fd025be2 [AP] Update version info 2019-09-03 03:26:35 +01:00
tenma
b5897687a6 [AP] Prevent postman to include the actor's followers for every sent activity 2019-09-03 03:26:35 +01:00
tenma
ebeae261de [AP] Support Private Messaging
ActivityPubPlugin:
- Subscribe DirectMessage events

Activitypub_inbox_handler:
- Update handle_create_note to create private messages

Activitypub_postman:
- Add create_direct_note for sending private messages

Activitypub_create:
- Update create_to_array to support the 'directMessage' attribute
- Add isPrivateNote to verify private activities

Activitypub_notice:
- Update create_note to support the 'directMessage' attribute
- Remove isPrivateNote

lib/models:
- Add Activitypub_message, the model in charge of private notes
2019-09-03 03:26:35 +01:00
tenma
9733f3c02c [AP] Fix Follow collections
Activitypub_profile:
- Fix subscription-counter getter functions, invalid profiles were being counted

apActorFollowingAction:
- Small rewrite of generate_following, didn't make sense to not use try-catch block

apActorFollowersAction:
- Small rewrite of generate_followers, didn't make sense to not use try-catch block
2019-09-03 03:26:35 +01:00
tenma
217c8a3933 [AP] Handle unlisted/followers-only notices
Note that this commit isn't intended to add support for sending such notes
in GS. Instead, we handle the reception, storage and direct reply to this
type of notices, in AP.

ActivityPubPlugin:
- Subscribe the event StartNoticeSave to hack answering non-public notes

Activitypub_create:
- Add 'directMessage' attribute to the Create activity, defaulting to false for now
- Update validation method: validate 'directMessage' and add debug

Activitypub_notice:
- Handle incoming unlisted/followers-only notes
- Add support for unlisted-replies
- Add method to verify private (direct) notices

inbox_handler:
- Add handler for CREATE Note
- Prepare logic for private-messaging
- Overall refactor: Class members were continuously being passed as function arguments without need

SharePlugin:
- Stop showing the announce button in non public posts
2019-09-03 03:26:35 +01:00
tenma
7188d81ad4 [AP] Properly target public notices
ActivityPubPlugin:
- Use TO as principal audience, CC as secondary
- Update note validation
2019-09-03 03:26:35 +01:00
Miguel Dantas
48cacd6d9d [RedisCache] Added plugin description, fixes 'empty msgid' error 2019-09-03 03:26:35 +01:00
Diogo Cordeiro
1e378a514d [OverwriteThemeBackground] This new plugin will let the admin set a custom background theme independent 2019-09-03 03:26:35 +01:00
Diogo Cordeiro
92ab5e18ee [ExtendedProfile] Fix Admin menu option 2019-08-24 01:59:42 +01:00
Diogo Cordeiro
b42af10905 [MODULES] Allow to delete third party plugins 2019-08-24 01:59:42 +01:00
Diogo Cordeiro
afe8158cb7 [MODULES] Allow to upload third party plugins
Fixed some bugs
2019-08-24 01:59:42 +01:00
Diogo Cordeiro
a05bea0af5 [MODULES] List all available plugins and allow enabling them via UI
Yet another revision of the Admin Plugin Management tool
2019-08-24 01:59:41 +01:00
Diogo Cordeiro
e1514a151c [DOCUMENTATION][DEVELOPERS][PLUGINS] Some updates to Plugins doc 2019-08-24 01:59:41 +01:00
Diogo Cordeiro
2a82cfdb2a [TagCloud] Add Readme 2019-08-24 01:59:40 +01:00
Diogo Cordeiro
49da433879 [SearchSub][README] No longer is a default plugin since 8614cd77 2019-08-24 01:59:40 +01:00
Diogo Cordeiro
92388e1734 [SamplePlugin] Review and update with the latest GNU social best practices 2019-08-24 01:59:40 +01:00
Diogo Cordeiro
3860c25dc0 [ConversationTree] Format the plugin, add strict typing and fix docblocks 2019-08-24 01:59:39 +01:00
Diogo Cordeiro
25ee5ed1f9 [OfflineBackup] Fix plugin 2019-08-24 01:59:39 +01:00
Diogo Cordeiro
566214ac62 [PLUGINS] Removed OpenX as the service doesn't exist anymore 2019-08-24 01:59:39 +01:00
Diogo Cordeiro
1459f10803 [GroupFavorited] Fix plugin 2019-08-24 01:59:38 +01:00
Diogo Cordeiro
0795a39459 [ExtendedProfile] Hide 'Extra fields' from profile when no field was created by the sysadmin 2019-08-24 01:59:38 +01:00
Diogo Cordeiro
e5831d6807 [ExtendedProfile] Allow to delete custom profile field 2019-08-24 01:59:38 +01:00
Diogo Cordeiro
88bdb5114f [Plugins] Incorporated GNUsocialExtendedProfile as part of ExtendedProfile
Also improved a lot of the plugin and made things in a way it would make sense
2019-08-24 01:59:37 +01:00
Diogo Cordeiro
90bd9088bb [GNUsocialProfileExtensions] Fixed plugin 2019-08-24 01:59:37 +01:00
Diogo Cordeiro
01cf8ab82c [PLUGINS] Removed GNUsocial{Photo, Photos, Video} as we don't need them anymore 2019-08-24 01:59:36 +01:00
Diogo Cordeiro
aee5506f00 [PLUGINS] Removed GeoURL as the service doesn't exist anymore 2019-08-24 01:59:36 +01:00
Diogo Cordeiro
b6183f2de1 [ForceGroup] Modernized plugin and improved documentation 2019-08-24 01:59:36 +01:00
Diogo Cordeiro
452e0fe553 [DEFAULT] Add 'DirectionDetector' as a default plugin 2019-08-24 01:59:35 +01:00
Diogo Cordeiro
2f341a3369 [ChooseTheme] Fixed plugin 2019-08-24 01:59:35 +01:00
Diogo Cordeiro
66e55d1a1f [BlankAd] Fixed plugin 2019-08-24 01:59:34 +01:00
Diogo Cordeiro
63fac32bc0 [Awesomeness] Fixed plugin 2019-08-24 01:59:34 +01:00
Diogo Cordeiro
aaeaeba57c [DEFAULT] Add 'AccountManager' as a default plugin 2019-08-24 01:59:34 +01:00
Diogo Cordeiro
d3c56897a3 [CORE] Core modules shouldn't show up in version action 2019-08-24 01:59:33 +01:00
Diogo Cordeiro
0c2c3ec862 [CORE] Plugin API now extends a new Module API 2019-08-24 01:59:33 +01:00
Diogo Cordeiro
b6e7b18c7b [PLUGIN API] Bug fixes and improvements 2019-08-24 01:59:32 +01:00
Diogo Cordeiro
55d049b1e8 [CORE] Move plugin superclasses from /lib/ to /lib/modules/ 2019-08-22 03:13:58 +01:00
Diogo Cordeiro
8c0601816f [CORE] Move core plugins to a new modules directory
For reference (raised by rozzin in IRC):

* http://foldoc.org/module
* http://foldoc.org/library
* http://foldoc.org/plugin

As noted by XRevan86, modules are not necessarily non-essential.
As we will keep the modules directory in GS root [therefore, near to
plugins/], it is evidenced the difference between both.

This is a simple yet fundamental structural change. It doesn't change
functionality but makes clearer the way we understand GNU social's
internals.
2019-08-22 03:13:58 +01:00
Miguel Dantas
350cde08d8 [Embed] Added support for inline images 2019-08-22 03:13:58 +01:00
tenma
db5a29fd9a [DirectMessage] Major plugin rework
This commit does the necessary rework to store private messages
as Notices and to support Federation. The plugin's README presents
some more detail about the changes and future work that is still
required to do.
2019-08-22 03:13:58 +01:00
tenma
0716605e94 [CORE][ROUTES] Update urlmapper to search dynamic routes before static ones when generating URLs.
This solves the problem of routes that differ only in having
or not $_GET params. The ones not having params (static) were
being matched first during URL generation.

The way this problem was solved was by separating the $reverse
array in both $reverse_statics and $reverse_dynamics and explicitly
traversing this last one first in the generation function. Note that
maintaining the $reverse array and unshifting dynamic routes to its
head ( and therefore to the front of the static ones ) doesn't work
since even among dynamic routes the order of arrival should be kept.
2019-08-22 03:13:58 +01:00
tenma
c802480d75 [CORE] Add new Notice scope for private messaging
Notice:
- Add MESSAGE_SCOPE scope

lib/*.stream:
- Filter out notices with MESSAGE_SCOPE scope
2019-08-21 16:54:47 +01:00
Miguel Dantas
2519431f02 [Embed] Added support for inline images 2019-08-21 16:54:46 +01:00
Miguel Dantas
b38e71e544 [Embed] Only resize thumbnail if it's bigger than the desired size 2019-08-21 16:54:46 +01:00
Diogo Cordeiro
c981afcf31 [DOCUMENTATION] Add release notes
Update INSTALL requirements
Update CHANGELOG
Update TODO
2019-08-21 16:54:09 +01:00
Diogo Cordeiro
eccb8a4faf [ActivityPub] Move models from 'classes' to 'lib/models' 2019-08-21 16:46:39 +01:00
tenma
7fa5ddfc44 [ActivityPub] Fix WebFinger event subscription
ActivityPubPlugin:
- remove reference to the first argument of onEndWebFingerProfileLinks, no need
as it is an object
2019-08-21 16:46:39 +01:00
tenma
054f4e77f5 [ActivityPub] Fix handling of Delete Activity
inbox_handler:
- Call stronger validation method for Delete Activity objects
- Take into account mixed object in handle_delete

Activitypub_delete:
- Add validation method for Delete Activity objects
2019-08-21 16:46:39 +01:00
Diogo Cordeiro
1398d6cc21 [ActivityPub] This is the first release of the plugin 2019-08-21 16:46:38 +01:00
tenma
b902b019fb [ActivityPub] Use queues for notice distribution
ActivityPubPlugin:
- Change event-based notice distribution to queues logic

ActivityPub/lib:
- Add queue handler class activitypubqueuehandler.php

Misc:
- Add documentation for the (Start/End)InitializeQueueManager events
2019-08-21 16:46:38 +01:00
tenma
5e589aba3c [OStatus] Fix notice enqueue
OStatusPlugin:
- Enqueue in the last position, as it should be. No need to worry about
the OMB comment, this protocol no longer have queue handlers that could
cause a conflict.
2019-08-21 16:46:38 +01:00
tenma
c28cee88b7 [ActivityPub] Ensuring federation with other software
ActivityPubPlugin:
- Prevent sending a Delete for an Announce

Activitypub_announce:
- Update announce_to_array to add id, to and cc information to the retrieved object

Activitypub_follow:
- Add id to the arguments of follow_to_array, useful for Accept-Follow activities

Activitypub_notice:
- Fix notice validation, url isn't a MUST

Activitypub_inbox_handler:
- Make handle_follow use the received activity id for the later Accept-Follow

Activitypub_postman:
- Fix call to the updated announce_to_array
- Fix successive unnecessary calls to ActivityPubPlugin::actor_uri()
2019-08-21 16:46:37 +01:00
brunoccast
14a45dc546 [ActivityPub] Fix notice creation
Activitypub_notice:
- Perform url test, use id when missing.
2019-08-21 16:46:37 +01:00
brunoccast
883621ba34 [ActivityPub] Routes
ActivityPubPlugin:
- Update routes to properly use the updated URLMapper
2019-08-21 16:46:37 +01:00
brunoccast
067cc81ebb [ActivityPub] Ensuring notice deletion
ActivityPubPlugin:
- Minor onDeleteOwnNotice rewrite

Activitypub_inbox_handler:
- Add deletion check to incoming notice

Activitypub_postman:
- Call the correct getUrl function
2019-08-21 16:46:37 +01:00
brunoccast
b19ee7b894 [ActivityPub] Ensuring Notice Favor/Disfavor
ActivityPubPlugin:
- Minor re-write of favor/disfavor event handlers

Activitypub_postman:
like/undo-like:
- fix proper getUrl() call
misc:
- make all activities accumulate errors (may be needed later) and log some information about it
2019-08-21 16:46:36 +01:00
brunoccast
1b356d3bf2 [ActivityPub] Ensuring notice distribution
ActivityPubPlugin:
- Fix of accepted activity verbs to include SHARES
- Add attention profiles to delivery when announcing

Activitypub_notice:
- New local function to retrieve original URL
- Removal of unnecessary 'Atom*' attributes
- Small fix to the ensuring of actor profile

Activitypub_profile:
- New local function to fetch AP profiles from a collection

Activitypub_postman:
- Fix url passed in the announce activity
2019-08-21 16:46:36 +01:00
brunoccast
94a4059b4a [ActivityPub] Caching of Following/Followers interactions and collections
Follow interaction:
- Fixed mini-bug where the subscriber profile was being used as the subscribed
- Updated cache subscription-related values in both instances
- Tested and working with local GS instances

Unfollow interaction:
- Updated cache subscription-related values in both instances
- Tested and working with local GS instances

Followers/Following collections:
- Now returning ActivityPub profiles only
- Stored collections in cache

Misc:
- Fix bug concerning the retrieval of public/private-key after in-function generation
2019-08-21 16:46:36 +01:00
brunoccast
735a0023cc [ActivityPub] Routes
ActivityPubPlugin:
- Update routes to properly use URLMapper
- Minor updates
2019-08-21 16:46:36 +01:00
Diogo Cordeiro
2ad4fa99ed [CORE] Add ActivityPub plugin
This is not the same as the one in https://notabug.org/diogo/gnu-social-activitypub-plugin
Differences to the first "release"
-> Doesn't use guzzle nor has any composer dependencies
-> Supports HTTP Signatures
-> Has basic l10n/i18n
-> Some minor bug fixes
2019-08-21 16:46:35 +01:00
Miguel Dantas
c0950c5fc6 [PLUGINS] Dropped Memcache in favor of Memcached. The difference between these is that they use a similarly php library to interact with memcache, but memcached is more modern 2019-08-15 22:33:38 +01:00
Miguel Dantas
afbbbbd4f2 [Memcached] Merged useful features from Memcache 2019-08-15 22:33:37 +01:00
Miguel Dantas
32812c9482 [PLUGINS] Updated and reviewed the Memcached plugin 2019-08-15 22:33:37 +01:00
Miguel Dantas
c70e806d74 [RedisCache] Added README with configuration instructions 2019-08-15 22:33:36 +01:00
Miguel Dantas
05be2e7386 [RedisCache] Fix use of undefined variable 2019-08-14 15:32:36 +01:00
Miguel Dantas
e2e8885ce3 [PLUGINS] Removed direct call of EndCache events on all plugins, as it is now handled by the library 2019-08-14 15:32:35 +01:00
Miguel Dantas
b214d8b6ee [CACHING] Imported Chimo's RedisCache plugin and fixed some small parts 2019-08-14 15:32:35 +01:00
Miguel Dantas
ba98bb9334 [CORE] Fixed small anti-pattern on cache code. Plugins had to throw EndCache events, when this should be done by the library 2019-08-14 15:32:35 +01:00
Miguel Dantas
630a578e1d [COMPOSER] Added predis/predis and updated packages 2019-08-14 15:32:34 +01:00
11392 changed files with 81037 additions and 1956213 deletions

3
.dir-locals.el Normal file
View File

@@ -0,0 +1,3 @@
((nil . ((php-project-root . auto)
(phpstan-executable . (root . "bin/phpstan"))
)

43
.env Normal file
View File

@@ -0,0 +1,43 @@
# In all environments, the following files are loaded if they exist,
# the latter taking precedence over the former:
#
# * .env contains default values for the environment variables needed by the app
# * .env.local uncommitted file with local overrides
# * .env.$APP_ENV committed environment-specific defaults
# * .env.$APP_ENV.local uncommitted environment-specific overrides
#
# Real environment variables win over .env files.
#
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
#
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
###> symfony/framework-bundle ###
APP_ENV=dev
APP_SECRET=6a9ac3a09c73230107373e8e0b71e0a3
#TRUSTED_PROXIES=127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
#TRUSTED_HOSTS='^(localhost|example\.com)$'
###< symfony/framework-bundle ###
###> symfony/mailer ###
# MAILER_DSN=smtp://localhost
###< symfony/mailer ###
###> doctrine/doctrine-bundle ###
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
# For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data.db"
# For a PostgreSQL database, use: "postgresql://db_user:db_password@127.0.0.1:5432/db_name?serverVersion=11&charset=utf8"
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
DATABASE_URL=postgresql://postgres:foobar@postgres:5432/social
#?serverVersion=11&charset=utf8
###< doctrine/doctrine-bundle ###
SHELL_VERBOSITY=3
###> symfony/messenger ###
# Choose one of the transports below
# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages
MESSENGER_TRANSPORT_DSN_HIGH=doctrine://default?queue_name=high
MESSENGER_TRANSPORT_DSN_LOW=doctrine://default?queue_name=low
# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
###< symfony/messenger ###

6
.env.test Normal file
View File

@@ -0,0 +1,6 @@
# define your env variables for the test env here
KERNEL_CLASS='App\Kernel'
APP_SECRET='$ecretf0rt3st'
SYMFONY_DEPRECATIONS_HELPER=999999
PANTHER_APP_ENV=panther
DATABASE_URL=postgresql://postgres:password@db:5432/test

81
.gitignore vendored
View File

@@ -1,19 +1,64 @@
avatar/
files/
file/
local/
logs/
log/
run/
config.php
.htaccess
httpd.conf
dataobject.ini
*.bak
*.orig
*.rej
TODO.rym
config-*.php
good-config.php
*.mo
###> symfony/framework-bundle ###
/.env.local
/.env.local.php
/.env.*.local
/config/secrets/prod/prod.decrypt.private.php
/public/bundles/
/var/
/vendor/
###< symfony/framework-bundle ###
###> symfony/phpunit-bridge ###
.phpunit
.phpunit.result.cache
/phpunit.xml
###< symfony/phpunit-bridge ###
###> friendsofphp/php-cs-fixer ###
!.php-cs-fixer.php
/.php_cs.cache
/.php-cs-fixer.cache
###< friendsofphp/php-cs-fixer ###
###> phpunit/phpunit ###
/phpunit.xml
.phpunit.result.cache
###< phpunit/phpunit ###
DOCUMENTATION/database/*
!DOCUMENTATION/database/database.pdf
docker/certbot/.files
docker/certbot/www
docker/*/*.env
docker/mail/etc/hostname
docker/mail/etc/hosts
docker/mail/etc/resolv.conf
docker/mail/config/aliases.db
docker/mail/config/domains.db
docker/mail/config/mailboxes.db
docker/mail/config/passwd.db
docker/mail/etc/service/*
!docker/mail/etc/service/*/run
!docker/testing/*
!docker/testing/docker-compose.yaml
docker/testing/*~
docker-compose.yaml
composer.local.json
social.local.yaml
# V2
config.php
/file
notes
.test_coverage_report
.phpunit_cache

378
.php-cs-fixer.php Normal file
View File

@@ -0,0 +1,378 @@
<?php
declare(strict_types = 1);
/*
* This document has been generated with
* https://mlocati.github.io/php-cs-fixer-configurator/#version:3.2.1|configurator
* you can change this configuration by importing this file.
*/
$config = new PhpCsFixer\Config();
return $config
->setRiskyAllowed(true)
->setRules([
// Each line of multi-line DocComments must have an asterisk [PSR-5] and must be aligned with the first one.
'align_multiline_comment' => ['comment_type' => 'phpdocs_like'],
// Each element of an array must be indented exactly once.
'array_indentation' => true,
// Converts simple usages of `array_push($x, $y);` to `$x[] = $y;`.
'array_push' => true,
// PHP arrays should be declared using the configured syntax.
'array_syntax' => ['syntax' => 'short'],
// Use the null coalescing assignment operator `??=` where possible.
'assign_null_coalescing_to_coalesce_equal' => true,
// Binary operators should be surrounded by space as configured.
'binary_operator_spaces' => ['default' => 'align_single_space_minimal', 'operators' => ['??' => 'align']],
// There MUST be one blank line after the namespace declaration.
'blank_line_after_namespace' => true,
// Ensure there is no code on the same line as the PHP open tag and it is followed by a blank line.
'blank_line_after_opening_tag' => true,
// The body of each structure MUST be enclosed by braces. Braces should be properly placed. Body of braces should be properly indented.
'braces' => ['allow_single_line_anonymous_class_with_empty_body' => true, 'allow_single_line_closure' => true, 'position_after_functions_and_oop_constructs' => 'next'],
// A single space or none should be between cast and variable.
'cast_spaces' => true,
// Whitespace around the keywords of a class, trait or interfaces definition should be one space.
'class_definition' => ['single_item_single_line' => true, 'single_line' => true],
// Using `isset($var) &&` multiple times should be done in one call.
'combine_consecutive_issets' => true,
// Calling `unset` on multiple items should be done in one call.
'combine_consecutive_unsets' => true,
// Replace multiple nested calls of `dirname` by only one call with second `$level` parameter. Requires PHP >= 7.0.
'combine_nested_dirname' => true,
// Comments with annotation should be docblock when used on structural elements.
'comment_to_phpdoc' => false,
// Remove extra spaces in a nullable typehint.
'compact_nullable_typehint' => true,
// Concatenation should be spaced according configuration.
'concat_space' => ['spacing' => 'one'],
// The PHP constants `true`, `false`, and `null` MUST be written using the correct casing.
'constant_case' => true,
// Equal sign in declare statement should be surrounded by spaces or not following configuration.
'declare_equal_normalize' => ['space' => 'single'],
// There must not be spaces around `declare` statement parentheses.
'declare_parentheses' => true,
// Force strict types declaration in all files. Requires PHP >= 7.0.
'declare_strict_types' => true,
// Replaces `dirname(__FILE__)` expression with equivalent `__DIR__` constant.
'dir_constant' => true,
// Replaces short-echo `<?=` with long format `<?php echo`/`<?php print` syntax, or vice-versa.
'echo_tag_syntax' => true,
// The keyword `elseif` should be used instead of `else if` so that all control keywords look like single words.
'elseif' => true,
// Empty loop-body must be in configured style.
'empty_loop_body' => true,
// Empty loop-condition must be in configured style.
'empty_loop_condition' => true,
// PHP code MUST use only UTF-8 without BOM (remove BOM).
'encoding' => true,
// Replace deprecated `ereg` regular expression functions with `preg`.
'ereg_to_preg' => true,
// Escape implicit backslashes in strings and heredocs to ease the understanding of which are special chars interpreted by PHP and which not.
'escape_implicit_backslashes' => true,
// Add curly braces to indirect variables to make them clear to understand. Requires PHP >= 7.0.
'explicit_indirect_variable' => true,
// Converts implicit variables into explicit ones in double-quoted strings or heredoc syntax.
'explicit_string_variable' => true,
// PHP code must use the long `<?php` tags or short-echo `<?=` tags and not other tag variations.
'full_opening_tag' => true,
// Transforms imported FQCN parameters and return types in function arguments to short version.
'fully_qualified_strict_types' => true,
// Spaces should be properly placed in a function declaration.
'function_declaration' => ['closure_function_spacing' => 'one'],
// Ensure single space between function's argument and its typehint.
'function_typehint_space' => true,
// Imports or fully qualifies global classes/functions/constants.
'global_namespace_import' => true,
// Heredoc/nowdoc content must be properly indented. Requires PHP >= 7.3.
'heredoc_indentation' => true,
// Convert `heredoc` to `nowdoc` where possible.
'heredoc_to_nowdoc' => true,
// Function `implode` must be called with 2 arguments in the documented order.
'implode_call' => true,
// Pre- or post-increment and decrement operators should be used if possible.
'increment_style' => true,
// Code MUST use configured indentation type.
'indentation_type' => true,
// Lambda must not import variables it doesn't use.
'lambda_not_used_import' => true,
// All PHP files must use same line ending.
'line_ending' => true,
// Ensure there is no code on the same line as the PHP open tag.
'linebreak_after_opening_tag' => true,
// List (`array` destructuring) assignment should be declared using the configured syntax. Requires PHP >= 7.1.
'list_syntax' => ['syntax' => 'short'],
// Use `&&` and `||` logical operators instead of `and` and `or`.
'logical_operators' => true,
// Cast should be written in lower case.
'lowercase_cast' => true,
// PHP keywords MUST be in lower case.
'lowercase_keywords' => true,
// Class static references `self`, `static` and `parent` MUST be in lower case.
'lowercase_static_reference' => true,
// Magic constants should be referred to using the correct casing.
'magic_constant_casing' => true,
// Magic method definitions and calls must be using the correct casing.
'magic_method_casing' => true,
// Replace non multibyte-safe functions with corresponding mb function.
'mb_str_functions' => true,
// In method arguments and method call, there MUST NOT be a space before each comma and there MUST be one space after each comma. Argument lists MAY be split across multiple lines, where each subsequent line is indented once. When doing so, the first item in the list MUST be on the next line, and there MUST be only one argument per line.
'method_argument_space' => ['after_heredoc' => true, 'on_multiline' => 'ensure_fully_multiline'],
// Method chaining MUST be properly indented. Method chaining with different levels of indentation is not supported.
'method_chaining_indentation' => true,
// Replace `strpos()` calls with `str_starts_with()` or `str_contains()` if possible.
'modernize_strpos' => true,
// Replaces `intval`, `floatval`, `doubleval`, `strval` and `boolval` function calls with according type casting operator.
'modernize_types_casting' => true,
// DocBlocks must start with two asterisks, multiline comments must start with a single asterisk, after the opening slash. Both must end with a single asterisk before the closing slash.
'multiline_comment_opening_closing' => true,
// Forbid multi-line whitespace before the closing semicolon or move the semicolon to the new line for chained calls.
'multiline_whitespace_before_semicolons' => true,
// Add leading `\` before constant invocation of internal constant to speed up resolving. Constant name match is case-sensitive, except for `null`, `false` and `true`.
'native_constant_invocation' => true,
// Function defined by PHP should be called using the correct casing.
'native_function_casing' => true,
// Add leading `\` before function invocation to speed up resolving.
'native_function_invocation' => true,
// Native type hints for functions should use the correct case.
'native_function_type_declaration_casing' => true,
// Master language constructs shall be used instead of aliases.
'no_alias_language_construct_call' => true,
// Replace control structure alternative syntax to use braces.
'no_alternative_syntax' => true,
// There should be no empty lines after class opening brace.
'no_blank_lines_after_class_opening' => true,
// There should not be blank lines between docblock and the documented element.
'no_blank_lines_after_phpdoc' => true,
// There must be a comment when fall-through is intentional in a non-empty case body.
'no_break_comment' => true,
// The closing `? >` tag MUST be omitted from files containing only PHP.
'no_closing_tag' => true,
// There should not be any empty comments.
'no_empty_comment' => true,
// There should not be empty PHPDoc blocks.
'no_empty_phpdoc' => true,
// Remove useless (semicolon) statements.
'no_empty_statement' => true,
// Removes extra blank lines and/or blank lines following configuration.
'no_extra_blank_lines' => true,
// Remove leading slashes in `use` clauses.
'no_leading_import_slash' => true,
// The namespace declaration line shouldn't contain leading whitespace.
'no_leading_namespace_whitespace' => true,
// Either language construct `print` or `echo` should be used.
'no_mixed_echo_print' => true,
// Operator `=>` should not be surrounded by multi-line whitespaces.
'no_multiline_whitespace_around_double_arrow' => true,
// Properties MUST not be explicitly initialized with `null` except when they have a type declaration (PHP 7.4).
'no_null_property_initialization' => true,
// Short cast `bool` using double exclamation mark should not be used.
'no_short_bool_cast' => true,
// Single-line whitespace before closing semicolon are prohibited.
'no_singleline_whitespace_before_semicolons' => true,
// There must be no space around double colons (also called Scope Resolution Operator or Paamayim Nekudotayim).
'no_space_around_double_colon' => true,
// When making a method or function call, there MUST NOT be a space between the method or function name and the opening parenthesis.
'no_spaces_after_function_name' => true,
// There MUST NOT be spaces around offset braces.
'no_spaces_around_offset' => true,
// There MUST NOT be a space after the opening parenthesis. There MUST NOT be a space before the closing parenthesis.
'no_spaces_inside_parenthesis' => true,
// Removes `@param`, `@return` and `@var` tags that don't provide any useful information.
'no_superfluous_phpdoc_tags' => false,
// Remove trailing commas in list function calls.
'no_trailing_comma_in_list_call' => true,
// PHP single-line arrays should not have trailing comma.
'no_trailing_comma_in_singleline_array' => true,
// Remove trailing whitespace at the end of non-blank lines.
'no_trailing_whitespace' => true,
// There MUST be no trailing spaces inside comment or PHPDoc.
'no_trailing_whitespace_in_comment' => true,
// Removes unneeded parentheses around control statements.
'no_unneeded_control_parentheses' => true,
// Removes unneeded curly braces that are superfluous and aren't part of a control structure's body.
'no_unneeded_curly_braces' => true,
// In function arguments there must not be arguments with default values before non-default ones.
'no_unreachable_default_argument_value' => true,
// Variables must be set `null` instead of using `(unset)` casting.
'no_unset_cast' => true,
// Unused `use` statements must be removed.
'no_unused_imports' => true,
// There should not be an empty `return` statement at the end of a function.
'no_useless_return' => true,
// In array declaration, there MUST NOT be a whitespace before each comma.
'no_whitespace_before_comma_in_array' => true,
// Remove trailing whitespace at the end of blank lines.
'no_whitespace_in_blank_line' => true,
// Remove Zero-width space (ZWSP), Non-breaking space (NBSP) and other invisible unicode symbols.
'non_printable_character' => true,
// Array index should always be written by using square braces.
'normalize_index_brace' => true,
// Adds or removes `?` before type declarations for parameters with a default `null` value.
'nullable_type_declaration_for_default_null_value' => true,
// There should not be space before or after object operators `->` and `?->`.
'object_operator_without_whitespace' => true,
// Operators - when multiline - must always be at the beginning or at the end of the line.
'operator_linebreak' => true,
// Ordering `use` statements.
'ordered_imports' => true,
// PHPUnit assertion method calls like `->assertSame(true, $foo)` should be written with dedicated method like `->assertTrue($foo)`.
'php_unit_construct' => true,
// PHPUnit assertions like `assertInternalType`, `assertFileExists`, should be used over `assertTrue`.
'php_unit_dedicate_assert' => true,
// PHPUnit assertions like `assertIsArray` should be used over `assertInternalType`.
'php_unit_dedicate_assert_internal_type' => true,
// Usages of `->setExpectedException*` methods MUST be replaced by `->expectException*` methods.
'php_unit_expectation' => true,
// PHPUnit annotations should be a FQCNs including a root namespace.
'php_unit_fqcn_annotation' => true,
// Enforce camel (or snake) case for PHPUnit test methods, following configuration.
'php_unit_method_casing' => true,
// Usage of PHPUnit's mock e.g. `->will($this->returnValue(..))` must be replaced by its shorter equivalent such as `->willReturn(...)`.
'php_unit_mock_short_will_return' => true,
// PHPUnit classes MUST be used in namespaced version, e.g. `\PHPUnit\Framework\TestCase` instead of `\PHPUnit_Framework_TestCase`.
'php_unit_namespaced' => true,
// Usages of `@expectedException*` annotations MUST be replaced by `->setExpectedException*` methods.
'php_unit_no_expectation_annotation' => true,
// Changes the visibility of the `setUp()` and `tearDown()` functions of PHPUnit to `protected`, to match the PHPUnit TestCase.
'php_unit_set_up_tear_down_visibility' => true,
// PHPUnit methods like `assertSame` should be used instead of `assertEquals`.
'php_unit_strict' => true,
// Calls to `PHPUnit\Framework\TestCase` static methods must all be of the same type, either `$this->`, `self::` or `static::`.
'php_unit_test_case_static_method_calls' => true,
// PHPDoc should contain `@param` for all params.
'phpdoc_add_missing_param_annotation' => true,
// All items of the given phpdoc tags must be either left-aligned or (by default) aligned vertically.
'phpdoc_align' => true,
// PHPDoc annotation descriptions should not be a sentence.
'phpdoc_annotation_without_dot' => true,
// Docblocks should have the same indentation as the documented subject.
'phpdoc_indent' => true,
// Fixes PHPDoc inline tags.
'phpdoc_inline_tag_normalizer' => true,
// Changes doc blocks from single to multi line, or reversed. Works for class constants, properties and methods only.
'phpdoc_line_span' => true,
// `@access` annotations should be omitted from PHPDoc.
'phpdoc_no_access' => true,
// No alias PHPDoc tags should be used.
'phpdoc_no_alias_tag' => true,
// `@return void` and `@return null` annotations should be omitted from PHPDoc.
'phpdoc_no_empty_return' => true,
// Classy that does not inherit must not have `@inheritdoc` tags.
'phpdoc_no_useless_inheritdoc' => true,
// Annotations in PHPDoc should be ordered so that `@param` annotations come first, then `@throws` annotations, then `@return` annotations.
'phpdoc_order' => true,
// Order phpdoc tags by value.
'phpdoc_order_by_value' => ['annotations' => ['covers', 'throws']],
// The type of `@return` annotations of methods returning a reference to itself must the configured one.
'phpdoc_return_self_reference' => true,
// Scalar types should always be written in the same form. `int` not `integer`, `bool` not `boolean`, `float` not `real` or `double`.
'phpdoc_scalar' => true,
// Annotations in PHPDoc should be grouped together so that annotations of the same type immediately follow each other, and annotations of a different type are separated by a single blank line.
'phpdoc_separation' => true,
// Single line `@var` PHPDoc should have proper spacing.
'phpdoc_single_line_var_spacing' => true,
// Fixes casing of PHPDoc tags.
'phpdoc_tag_casing' => true,
// Would be neat, but breaks cases where the parents don't have annotations
// // EXPERIMENTAL: Takes `@param` annotations of non-mixed types and adjusts accordingly the function signature. Requires PHP >= 7.0.
// 'phpdoc_to_param_type' => true,
// // EXPERIMENTAL: Takes `@var` annotation of non-mixed types and adjusts accordingly the property signature. Requires PHP >= 7.4.
// 'phpdoc_to_property_type' => true,
// // EXPERIMENTAL: Takes `@return` annotation of non-mixed types and adjusts accordingly the function signature. Requires PHP >= 7.0.
// 'phpdoc_to_return_type' => true,
// PHPDoc should start and end with content, excluding the very first and last line of the docblocks.
'phpdoc_trim' => true,
// Removes extra blank lines after summary and after description in PHPDoc.
'phpdoc_trim_consecutive_blank_line_separation' => true,
// The correct case must be used for standard PHP types in PHPDoc.
'phpdoc_types' => true,
// Sorts PHPDoc types.
'phpdoc_types_order' => true,
// `@var` and `@type` annotations must have type and name in the correct order.
'phpdoc_var_annotation_correct_order' => true,
// Converts `pow` to the `**` operator.
'pow_to_exponentiation' => true,
// Replaces `rand`, `srand`, `getrandmax` functions calls with their `mt_*` analogs or `random_int`.
'random_api_migration' => true,
// Callables must be called without using `call_user_func*` when possible.
'regular_callable_call' => true,
// Local, dynamic and directly referenced variables should not be assigned and directly returned by a function or method.
'return_assignment' => true,
// There should be one or no space before colon, and one space after it in return type declarations, according to configuration.
'return_type_declaration' => true,
// Inside class or interface element `self` should be preferred to the class name itself.
'self_accessor' => true,
// Instructions must be terminated with a semicolon.
'semicolon_after_instruction' => true,
// Cast shall be used, not `settype`.
'set_type_to_cast' => true,
// Cast `(boolean)` and `(integer)` should be written as `(bool)` and `(int)`, `(double)` and `(real)` as `(float)`, `(binary)` as `(string)`.
'short_scalar_cast' => true,
// Converts explicit variables in double-quoted strings and heredoc syntax from simple to complex format (`${` to `{$`).
'simple_to_complex_string_variable' => true,
// Simplify `if` control structures that return the boolean result of their condition.
'simplified_if_return' => true,
// A return statement wishing to return `void` should not return `null`.
'simplified_null_return' => true,
// A PHP file without end tag must always end with a single empty line feed.
'single_blank_line_at_eof' => true,
// There should be exactly one blank line before a namespace declaration.
'single_blank_line_before_namespace' => true,
// There MUST NOT be more than one property or constant declared per statement.
'single_class_element_per_statement' => true,
// There MUST be one use keyword per declaration.
'single_import_per_statement' => true,
// Each namespace use MUST go on its own line and there MUST be one blank line after the use statements block.
'single_line_after_imports' => true,
// Single-line comments and multi-line comments with only one line of actual content should use the `//` syntax.
'single_line_comment_style' => true,
// Convert double quotes to single quotes for simple strings.
'single_quote' => true,
// Ensures a single space after language constructs.
'single_space_after_construct' => true,
// Each trait `use` must be done as single statement.
'single_trait_insert_per_statement' => true,
// Fix whitespace after a semicolon.
'space_after_semicolon' => true,
// Increment and decrement operators should be used if possible.
'standardize_increment' => true,
// Replace all `<>` with `!=`.
'standardize_not_equals' => true,
// String tests for empty must be done against `''`, not with `strlen`.
'string_length_to_empty' => true,
// A case should be followed by a colon and not a semicolon.
'switch_case_semicolon_to_colon' => true,
// Removes extra spaces between colon and case value.
'switch_case_space' => true,
// Switch case must not be ended with `continue` but with `break`.
'switch_continue_to_break' => true,
// Standardize spaces around ternary operator.
'ternary_operator_spaces' => true,
// Use the Elvis operator `?:` where possible.
'ternary_to_elvis_operator' => true,
// Use `null` coalescing operator `??` where possible. Requires PHP >= 7.0.
'ternary_to_null_coalescing' => true,
// Multi-line arrays, arguments list and parameters list must have a trailing comma.
'trailing_comma_in_multiline' => ['after_heredoc' => true, 'elements' => ['arguments', 'arrays', 'parameters']],
// Arrays should be formatted like function/method arguments, without leading or trailing single line space.
'trim_array_spaces' => true,
// A single space or none should be around union type operator.
'types_spaces' => true,
// Unary operators should be placed adjacent to their operands.
'unary_operator_spaces' => true,
// Anonymous functions with one-liner return statement must use arrow functions.
'use_arrow_functions' => true,
// Visibility MUST be declared on all properties and methods; `abstract` and `final` MUST be declared before the visibility; `static` MUST be declared after the visibility.
'visibility_required' => true,
// In array declaration, there MUST be a whitespace after each comma.
'whitespace_after_comma_in_array' => true,
])
->setFinder(
PhpCsFixer\Finder::create()
->exclude('vendor')
->exclude('var')
->exclude('docker')
->exclude('src/Entity')
->notPath('src/Core/DB/DefaultSettings.php')
->in(__DIR__),
);

View File

@@ -1,139 +0,0 @@
# GNU social - Log of Changes
## 2.0.0 - THIS. IS. GNU SOCIAL!!! [WIP]
Release name chosen after 300 by Frank Miller where the main protagonist Leonidas, King of Sparta, declines peace with the
Persians, after being disrespected, by shouting at the Persian Messenger "This is Sparta!" and kicking him into a large well
proceeded by the killing of the other Persian messengers.
### Major changes from previous release:
Load and Storage:
- New media handling system
- GS is now structurely divided in includes and public
- OEmbed upgraded to Embed plugin (Now we provide Open Graph information too)
General:
- Composer was integrated
Modules:
- Restored built-in plugins
- New modules system: core plugins and plugins physically separated
- Refactor of Plugin API to better illustrate the idea of modules
- Bug fixes of core modules logic
#### TODO before alpha:
Load and Storage:
- Upgrade STOMP queue
- Add Redis based caching and queues
- Review memcached based cache
- Port PEAR DB to PDO_DataObject
- Support PostgreSQL
Network:
- Port PEAR HTTP to Guzzle
- Port PEAR Mail to PHPSendMail
- Add OAuth2 support (deprecate OAuth1)
- Add shinny new Plugins management interface for sysadmins together with a new doc for devs
Federation:
- Add ActivityPub support
- Fix audience targeting
- Add Group Actor Type
- OstatusSub: Remote follow OS and AP profiles via OStatusSub
- ActorLists: Allow to create collections of Actors and to interact with them - supports both OS and AP
- The Free Network: Automagically migrate internal remote profiles between Free Network protocols (check Nodeinfo)
- Enable the search box to import remote notices and profiles
General:
- Fix failling unit tests
- Improve Cronish
- Run session garbage collection
- Cleanup Email Registration
- Refactoring of confirmation codes
- Refactoring of Exceptions
Modules:
- Document conversion of older plugins to the new GS 2
- Create installer for v2 plugins
- Introduce new metadata for plugins (category and thumb)
- Improve plugin management tool (add install form and better UI that makes use of new metadata)
- Add plugin management tool as a install step
- Allow to install remote plugins and suggest popular trusted ones
## v1.20.9release - The Invicta Crusade
Release name chosen after Porto city. Porto is one of the oldest cities in Europe and thanks to its fierce resistance
during two battles and sieges in history, it has earned the epithet of Cidade Invicta (Invincible City). The dev team
behind this release studies in Porto, Portugal.
Dropped Support for PHP5.6.x. Minimum PHP version now is 7.0.0.
Major changes from previous release:
- Various patches on PEAR related components
- Various database related improvements
- Improved XMPP support
- Added Nodeinfo support
- Various i18n and l10n bug fixes
- Improvements on Internal Session Handler
- Improvements on OpenID support
- Improved Media handling and safer upload
- Redirect to previous page after login
- Initial work on full conversion to PHP7
- Initial work on a better documentation
- Allow login with email
- Various bug fixes
## v1.2.0beta4 - The good reign of PHP5
Dropped support for PHP5.4.
New this version
This is the development branch for the 1.2.x version of GNU social. All daring 1.1.x admins should upgrade to this version.
So far it includes the following changes:
- Backing up a user's account is more and more complete.
- Emojis 😸 (utf8mb4 support)
The last release, 1.1.3, gave us these improvements:
- XSS security fix (thanks Simon Waters, https://www.surevine.com/)
- Many improvements to ease adoption of the Qvitter front-end https://github.com/hannesmannerheim/qvitter
- Protocol adaptions for improved performance and stability
Upgrades from StatusNet 1.1.1 will also experience these improvements:
- Fixes for SQL injection errors in profile lists.
- Improved ActivityStreams JSON representation of activities and objects.
- Upgrade to the Twitter 1.1 API.
- More robust handling of errors in distribution.
- Fix error in OStatus subscription for remote groups.
- Fix error in XMPP distribution.
- Tracking of conversation URI metadata (more coherent convos)
## v1.1.3release - The Spanish Invasion
New this version
This is a security fix and bug fix release since 1.1.3-beta2. All 1.1.x sites should upgrade to this version.
So far it includes the following changes:
- XSS security fix (thanks Simon Waters, https://www.surevine.com/)
- Many improvements to ease adoption of the Qvitter front-end https://github.com/hannesmannerheim/qvitter
- Protocol adaptions for improved performance and stability
- Backing up a user's account now appears to work as it should
Upgrades from StatusNet 1.1.1 will also experience these improvements:
- Fixes for SQL injection errors in profile lists.
- Improved ActivityStreams JSON representation of activities and objects.
- Upgrade to the Twitter 1.1 API.
- More robust handling of errors in distribution.
- Fix error in OStatus subscription for remote groups.
- Fix error in XMPP distribution.
- Tracking of conversation URI metadata (more coherent convos)

View File

@@ -1,95 +0,0 @@
## Code of Conduct
### Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
### Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
### Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
### Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
### Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at mattl@gnu.org. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
### Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
## The Code of Conflict
GNU social has a high submission standard and we want to keep quality code in the
codebase and bad code out of it. As such your code will be closely scrutinized,
and you might take this criticism personally. Please understand that this is
meant to keep the standards of the codebase up, and isn't meant personally. All
the same, this isn't an excuse for poor behaviour, and a reviewer shouldn't be
misbehaving towards submitters.
If however, anyone feels personally abused, threatened, or otherwise
uncomfortable due to this process, that is not acceptable. If so, please
contact the project team at mattl@gnu.org, and they will work to resolve the issue
to the best of their ability.
As a reviewer of code, please strive to keep things civil and focused on the
technical issues involved. We are all humans, and frustrations can be high on
both sides of the process. Try to keep in mind the immortal words of Bill and
Ted, "Be excellent to each other."

View File

@@ -1 +0,0 @@
GNU social's contributing resources and instructions are made available at [DOCUMENTATION/DEVELOPERS](https://notabug.org/diogo/gnu-social/src/nightly/DOCUMENTATION/DEVELOPERS).

661
COPYING
View File

@@ -1,661 +0,0 @@
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
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
them 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.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey 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;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If 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 convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero 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 that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
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.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
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.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
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
state 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 Affero General Public License as published by
the Free Software Foundation, either version 3 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<http://www.gnu.org/licenses/>.

View File

@@ -3,60 +3,66 @@ Credits for GNU social
The following is an incomplete list of developers
who've worked on GNU social, or its predecessors
StatusNet and Free Social. Apologies for any
oversight; please let mattl@gnu.org know if
oversight; please let mail@diogo.site know if
anyone's been overlooked in error.
Current team
------------
* Matt Lee
* Mikael Nordfeldth
* Diogo Cordeiro
* Bruno Casteleiro
* Miguel Dantas
* Alexei Sorokin
* Diogo Cordeiro
* Eliseu Amaro
* Hugo Sales
V2 team
-------
* Diogo Cordeiro
* Alexei Sorokin
* Bruno Casteleiro
Additional Contributors
-----------------------
* Ciaran Gultnieks
* Michael Landers
* Ori Avtalion
* Garret Buell
* Mike Cochrane
* Matthew Gregg
* Sean Murphy
* Leslie Michael Orchard
* Eric Helgeson
* Ken Sedgwick
* Brian Hendrickson
* Tobias Diekershoff
* Dan Moore
* Fil
* Jeff Mitchell
* Brenda Wallace
* Jeffery To
* Federico Marani
* mEDI
* Brett Taylor
* Brigitte Schuster
* Craig Andrews
* Donald Robertson
* Deb Nicholson
* Ian Denhart
* Steven DuBois
* Blaine Cook
* Henry Story
* Melvin Carvalho
* chimo
* Akio
* Maiyannah Bishop
* Blaine Cook
* Bob Mottram
* David Yip
* Neil E Hodges
* Moonman
* Normandy
* Verius
* Alexei Sorokin
* Brenda Wallace
* Brett Taylor
* Brian Hendrickson
* Brigitte Schuster
* Ciaran Gultnieks
* Craig Andrews
* Daniel Supernault
* Dan Moore
* David Yip
* Deb Nicholson
* Donald Robertson
* Eric Helgeson
* Federico Marani
* Fil
* Garret Buell
* Henry Story
* Ian Denhart
* Jeffery To
* Jeff Mitchell
* Ken Sedgwick
* Leslie Michael Orchard
* Maiyannah Bishop
* Matthew Gregg
* Matt Lee
* mEDI
* Melvin Carvalho
* Michael Landers
* Miguel Dantas
* Mikael Nordfeldth
* Mike Cochrane
* Moonman
* Neil E Hodges
* Normandy
* Ori Avtalion
* Sean Murphy
* Stéphane Bérubé
* Steven DuBois
* Tobias Diekershoff
* Verius
Credits for StatusNet
--------------
@@ -65,24 +71,24 @@ Leads
* Zach Copley
Team
* Earle Martin
* Marie-Claude Doyon
* Sarven Capadisli
* Robin Millette
* Brion Vibber
* James Walker
* Samantha Doherty
* Florian Biree
* Erik Stambaugh
* 'drry'
* Gina Haeussge
* Tryggvi Björgvinsson
* Adrian Lang
* Ori Avtalion
* Meitar Moscovitz
* Ken Sheppardson
* Simon Waters, Surevine
* Brion Vibber
* 'drry'
* Earle Martin
* Erik Stambaugh
* Florian Biree
* Gina Haeussge
* James Walker
* Joshua Judson Rosen (rozzin)
* Ken Sheppardson
* Marie-Claude Doyon
* Meitar Moscovitz
* Ori Avtalion
* Robin Millette
* Samantha Doherty
* Sarven Capadisli
* Simon Waters, Surevine
* Tryggvi Björgvinsson
Translators
-----------

View File

@@ -1,61 +0,0 @@
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Description of this file.
*
* @package samples
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
namespace samples;
defined('GNUSOCIAL') || die();
require_once __DIR__ . DIRECTORY_SEPARATOR . 'SampleHandler.php';
/**
* Description of this class.
*
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
class MySampleClass
{
/**
* Constructor for the sample class.
*
* @param string $dummy_word just because.
* @param int $result another just because.
*/
public function __construct(string $dummy_word = '', ?int $result = null)
{
global $demo;
$this->niceWorld();
}
/**
* How cool is this function.
*
* @return string
*/
public function niceWorld(): string
{
return 'hello, world.';
}
}

View File

@@ -1,275 +0,0 @@
GNU social Coding Style
===========================
Please comply with [PSR-2](https://www.php-fig.org/psr/psr-2/) and the following standard when working on GNU social
if you want your patches accepted and modules included in supported releases.
If you see code which doesn't comply with the below, please fix it :)
Strings
-------------------------------------------------------------------------------
Use `'` instead of `"` for strings, where substitutions aren't required.
This is a performance issue, and prevents a lot of inconsistent coding styles.
When using substitutions, use curly braces around your variables - like so:
$var = "my_var: {$my_var}";
Comments and Documentation
-------------------------------------------------------------------------------
Comments go on the line ABOVE the code, NOT to the right of the code, unless it is very short.
All functions and methods are to be documented using PhpDocumentor - https://docs.phpdoc.org/guides/
File Headers
-------------------------------------------------------------------------------
File headers follow a consistent format, as such:
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
/**
* Description of this file.
*
* @package samples
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
Please use it.
A few notes:
* The description of the file doesn't have to be exhaustive. Rather it's
meant to be a short summary of what's in this file and what it does. Try
to keep it to 1-5 lines. You can get more in-depth when documenting
individual functions!
* You'll probably see files with multiple authors, this is by
design - many people contributed to GNU social or its forebears! If you
are modifying an existing file, APPEND your own author line, and update
the copyright year if needed. Do not replace existing ones.
You may find `boilerplate.php` useful when creating a new file from scratch.
Paragraph spacing
-------------------------------------------------------------------------------
Where-ever possible, try to keep the lines to 80 characters. Don't
sacrifice readability for it though - if it makes more sense to have it in
one longer line, and it's more easily read that way, that's fine.
With assignments, avoid breaking them down into multiple lines unless
neccesary, except for enumerations and arrays.
'If' statements format
-------------------------------------------------------------------------------
Use switch statements where many else if's are going to be used. Switch/case is faster
if ($var == 'example') {
echo 'This is only an example';
} else {
echo 'This is not a test. This is the real thing';
}
Do NOT make if statements like this:
if ($var == 'example'){ echo 'An example'; }
OR this
if($var = 'example')
echo "An {$var}";
Associative arrays
-------------------------------------------------------------------------------
Always use `[]` instead of `array()`. Associative arrays must be written in the
following manner:
$array = [
'var' => 'value',
'var2' => 'value2'
];
Note that spaces are preferred around the '=>'.
A note about shorthands
-------------------------------------------------------------------------------
Some short hands are evil:
- Use the long format for `<?php`. Do NOT use `<?`.
- Use the long format for `<?php` echo. Do NOT use `<?=`.
Naming conventions
-------------------------------------------------------------------------------
Respect PSR2 first.
- Classes use PascalCase (e.g. MyClass).
- Functions/Methods use camelCase (e.g. myFunction).
- Variables use snake_case (e.g. my_variable).
A note on variable names, etc. It must be possible to understand what is meant
without neccesarialy seeing it in context, because the code that calls something
might not always make it clear.
So if you have something like:
$notice->post($contents);
Well I can easily tell what you're doing there because the names are straight-
forward and clear.
Something like this:
foo->bar();
Is much less clear.
Also, whereever possible, avoid ambiguous terms. For example, don't use text
as a term for a variable. Call back to "contents" above.
Comparisons
-------------------------------------------------------------------------------
Always use symbol based comparison operators (&&, ||) instead of text based
operators (AND, OR) as they are evaluated in different orders and at different
speeds. This is will prevent any confusion or strange results.
Use English
-------------------------------------------------------------------------------
All variables, classes, methods, functions and comments must be in English.
Bad english is easier to work with than having to babelfish code to work out
how it works.
Encoding
-------------------------------------------------------------------------------
Files should be in UTF-8 encoding with UNIX line endings.
No ending tag
-------------------------------------------------------------------------------
Files should not end with an ending php tag "?>". Any whitespace after the
closing tag is sent to the browser and cause errors, so don't include them.
Nesting Functions
-------------------------------------------------------------------------------
Avoid, if at all possible. When not possible, document the living daylights
out of why you're nesting it. It's not always avoidable, but PHP 5 has a lot
of obscure problems that come up with using nested functions.
If you must use a nested function, be sure to have robust error-handling.
This is a must and submissions including nested functions that do not have
robust error handling will be rejected and you'll be asked to add it.
Scoping
-------------------------------------------------------------------------------
Properly enforcing scope of functions is something many PHP programmers don't
do, but should.
In general:
* Variables unique to a class should be protected and use interfacing to
change them. This allows for input validation and making sure we don't have
injection, especially when something's exposed to the API, that any program
can use, and not all of them are going to be be safe and trusted.
* Variables not unique to a class should be validated prior to every call,
which is why it's generally not a good idea to re-use stuff across classes
unless there's significant performance gains to doing so.
* Classes should protect functions that they do not want overriden, but they
should avoid protecting the constructor and destructor and related helper
functions as this prevents proper inheritance.
Typecasting
-------------------------------------------------------------------------------
PHP is a soft-typed language and it falls to us developers to make sure that
we are using the proper inputs. Where ever possible use explicit type casting.
Where it in't, you're going to have to make sure that you check all your
inputs before you pass them.
All outputs should be cast as an explicit PHP type.
Not properly typecasting is a shooting offence. Soft types let programmers
get away with a lot of lazy code, but lazy code is buggy code, and frankly, I
don't want it in GNU social if it's going to be buggy.
Consistent exception handling
-------------------------------------------------------------------------------
Consistency is key to good code to begin with, but it is especially important
to be consistent with how we handle errors. GNU social has a variety of built-
in exception classes. Use them, wherever it's possible and appropriate, and
they will do the heavy lifting for you.
Additionally, ensure you clean up any and all records and variables that need
cleanup in a function using try { } finally { } even if you do not plan on
catching exceptions (why wouldn't you, though? That's silly.)
If you do not call an exception handler, you must, at a minimum, record errors
to the log using common_log(level, message)
Ensure all possible control flows of a function have exception handling and
cleanup, where appropriate. Don't leave endpoints with unhandled exceptions.
Try not to leave something in an error state if it's avoidable.
Return values
-------------------------------------------------------------------------------
All functions must return a value. Every single one. This is not optional.
If you are simply making a procedure call, for example as part of a helper
function, then return boolean TRUE on success, and the exception on failure.
When returning the exception, return the whole nine yards, which is to say the
actual PHP exception object, not just an error message.
All return values not the above should be type cast, and you should sanitize
anything returned to ensure it fits into the cast. You might technically make
an integer a string, for instance, but you should be making sure that integer
SHOULD be a string, if you're returning it, and that it is a valid return
value.
A vast majority of programming errors come down to not checking your inputs
and outputs properly, so please try to do so as best and thoroughly as you can.
Layout and Location of files
-------------------------------------------------------------------------------
`/actions/` contains files that determine what happens when something "happens":
for instance, when someone favourites or repeats a notice. Code that is
related to a "happening" should go here.
`/classes/` contains abstract definitions of certain "things" in the codebase
such as a user or notice. If you're making a new "thing", it goes here.
`/lib/` is basically the back-end. Actions will call something in here to get
stuff done usually, which in turn will probably manipulate information stored
in one or more records represented by a class.
`/extlib/` is where external libraries are located. If you include a new
external library, it goes here.
`/plugins/` This is a great way to modularize your own new features. If you want
to create new core features for GNU social, it is probably best to create a
module unless you absolutely must override or modify the core behaviours.

View File

@@ -1,32 +0,0 @@
Submission Checklist
================================================================================
This document serves as a handy checklist for submitted merges and patches to
the GNU social project. Following it isn't a gaurantee a patch will be accepted,
but it will help you avoid common problems.
1. Ensure all code control paths in all functions return a value.
2. Ensure all exceptions are trapped in an exception class, or minimally,
written to the log with common_log
3. Ensure the coding format standards are adhered to (see coding_standards.md)
4. Ensure that any new class that deals in public data has a corresponding new
API endpoint.
5. Ensure that all new API endpoints sanitize inputs and outputs properly.
6. Ensure that your version of the code works with PHP 7 on a standard
LAMP and LEMP stack (Linux+Apache+MariaDB+PHP and Linux+nginx+MariaDB+PHP)
7. If implementing new database functions, ensure they work with MariaDB
and postgreSQL.
8. Ensure all data that federates does so properly and has mechanisms to
catch and accomodate for federation transmission failure.
9. Ensure that nothing is left in an error state when it is avoidable.
10. Ensure that all code submitted is properly documented.
11. Ensure that there are no PHP Strict Standards or Parse errors in the code.

File diff suppressed because it is too large Load Diff

View File

@@ -1,355 +0,0 @@
Plugin Development
=======================
SamplePlugin.php
-----------------------
Each plugin requires a main class to interact with the GNU social system.
The main class usually extends the Plugin class that comes with GNU social.
The class has standard-named methods that will be called when certain events
happen in the code base. These methods have names like 'onX' where X is an
event name (see EVENTS.txt for the list of available events). Event handlers
have pre-defined arguments, based on which event they're handling. A typical
event handler:
```php
function onSomeEvent($paramA, &$paramB)
{
if ($paramA == 'jed') {
throw new Exception(sprintf(_m("Invalid parameter %s"), $paramA));
}
$paramB = 'spock';
return true;
}
```
Event Handlers
-----------------------
Event handlers must return a Boolean value.
If they return false, all other event handlers for this event (in other plug-in)
will be skipped, and in some cases the default processing for that event would
be skipped. This is great for replacing the default action of an event.
If the handler returns true, processing of other event handlers and the default
processing will continue. This is great for extending existing functionality.
If the handler throws an exception, processing will stop, and the exception's
error will be shown to the user.
Installation
------------------
To install a plugin (like this one), site admins add the following code to their
config.php file:
```php
addPlugin('Sample');
```
Plugins must be installed in one of the following directories:
* local/plugins/{$pluginclass}.php
* local/plugins/{$name}/{$pluginclass}.php
* local/{$pluginclass}.php
* local/{$name}/{$pluginclass}.php
* plugins/{$pluginclass}.php
* plugins/{$name}/{$pluginclass}.php
Here, `{$name}` is the name of the plugin, like 'Sample', and `{$pluginclass}`
is the name of the main class, like 'SamplePlugin'. Plugins that are part of
the main GNU social distribution go in 'plugins' and third-party or local ones
go in 'local'.
Simple plugins can be implemented as a single module. Others are more complex
and require additional modules; these should use their own directory, like
'local/plugins/{$name}/'. All files related to the plugin, including images,
JavaScript, CSS, external libraries or PHP modules should go in the plugin
directory.
Plugin Configuration
------------------
Plugins are configured using public instance attributes. To set their values,
site administrators use this syntax:
```php
addPlugin('Sample', ('attr1' => 'foo', 'attr2' => 'bar'));
```
The same plugin class can be initialized multiple times with different arguments:
```php
addPlugin('EmailNotify', array('sendTo' => 'evan@status.net'));
addPlugin('EmailNotify', array('sendTo' => 'brionv@status.net'));
```
```php
class SamplePlugin extends Plugin
{
public $attr1 = null;
public $attr2 = null;
}
```
Initialization
------------------
Plugins overload this method to do any initialization they need, like connecting
to remote servers or creating paths or so on. @return boolean hook value; true
means continue processing, false means stop.
```php
function initialize()
{
return true;
}
```
Clean Up
------------------
Plugins overload this method to do any cleanup they need, like disconnecting from
remote servers or deleting temp files or so on.
```php
function cleanup()
{
return true;
}
```
Database schema setup
------------------
Plugins can add their own tables to the GNU social database. Plugins should use
GNU social's schema interface to add or delete tables. The ensureTable() method
provides an easy way to ensure a table's structure and availability.
By default, the schema is checked every time GNU social is run (say, when a Web
page is hit). Admins can configure their systems to only check the schema when
the checkschema.php script is run, greatly improving performance. However, they
need to remember to run that script after installing or upgrading a plugin!
```php
function onCheckSchema()
{
$schema = Schema::get();
// '''For storing user-submitted flags on profiles'''
$schema->ensureTable('user_greeting_count',
array(new ColumnDef('user_id', 'integer', null,
true, 'PRI'),
new ColumnDef('greeting_count', 'integer')));
return true;
}
```
Load related modules when needed
------------------
Most non-trivial plugins will require extra modules to do their work. Typically
these include data classes, action classes, widget classes, or external libraries.
This method receives a class name and loads the PHP file related to that class.
By tradition, action classes typically have files named for the action, all
lower-case. Data classes are in files with the data class name, initial letter
capitalized.
Note that this method will be called for *all* overloaded classes, not just ones
in this plugin! So, make sure to return true by default to let other plugins,
and the core code, get a chance.
```php
function onAutoload($cls)
{
$dir = dirname(__FILE__);
switch ($cls)
{
case 'HelloAction':
include_once $dir . '/' . strtolower(mb_substr($cls, 0, -6)) . '.php';
return false;
case 'User_greeting_count':
include_once $dir . '/'.$cls.'.php';
return false;
default:
return true;
}
}
```
Map URLs to actions
------------------
This event handler lets the plugin map URLs on the site to actions (and thus an
action handler class). Note that the action handler class for an action will be
named 'FoobarAction', where action = 'foobar'. The class must be loaded in the
onAutoload() method.
```php
function onRouterInitialized($m)
{
$m->connect('main/hello',
array('action' => 'hello'));
return true;
}
```
Modify the default menu to link to our custom action
------------------
Using event handlers, it's possible to modify the default UI for pages almost
without limit. In this method, we add a menu item to the default primary menu
for the interface to link to our action.
Action Class
------------------
The Action class provides a rich set of events to hook, as well as output methods.
```php
function onEndPrimaryNav($action)
{
// '''common_local_url()''' gets the correct URL for the action name we provide
$action->menuItem(common_local_url('hello'),
_m('Hello'), _m('A warm greeting'), false, 'nav_hello');
return true;
}
function onPluginVersion(&$versions)
{
$versions[] = array('name' => 'Sample',
'version' => STATUSNET_VERSION,
'author' => 'Brion Vibber, Evan Prodromou',
'homepage' => 'http://example.org/plugin',
'rawdescription' =>
_m('A sample plugin to show basics of development for new hackers.'));
return true;
}
```
hello.php
------------------
This section is taken directly from the 'hello.php'. ( plugins/Sample/hello.php )
Give a warm greeting to our friendly user.
This sample action shows some basic ways of doing output in an action class.
Action classes have several output methods that they override from the parent class.
```php
class HelloAction extends Action
{
var $user = null;
var $gc = null;
}
```
Take arguments for running
------------------
This method is called first, and it lets the action class get all its arguments
and validate them. It's also the time to fetch any relevant data from the database.
Action classes should run parent::prepare(array $args = []) as the first line
of this method to make sure the default argument-processing happens.
```php
function prepare(array $args = [])
{
parent::prepare($args);
$this->user = common_current_user();
if (!empty($this->user)) {
$this->gc = User_greeting_count::inc($this->user->id);
}
return true;
}
```
Handle request
------------------
This is the main method for handling a request. Note that most preparation
should be done in the prepare() method; by the time handle() is called the
action should be more or less ready to go.
```php
function handle()
{
parent::handle();
$this->showPage();
}
```
Title of this page
------------------
Override this method to show a custom title.
```php
function title()
{
if (empty($this->user)) {
return _m('Hello');
} else {
return sprintf(_m('Hello, %s'), $this->user->nickname);
}
}
```
Show content in the content area
------------------
The default GNU social page has a lot of decorations: menus, logos, tabs, all
that jazz. This method is used to show content in the content area of the
page; it's the main thing you want to overload. This method also demonstrates
use of a plural localized string.
```php
function showContent()
{
if (empty($this->user)) {
$this->element('p', array('class' => 'greeting'),
_m('Hello, stranger!'));
} else {
$this->element('p', array('class' => 'greeting'),
sprintf(_m('Hello, %s'), $this->user->nickname));
$this->element('p', array('class' => 'greeting_count'),
sprintf(_m('I have greeted you %d time.',
'I have greeted you %d times.',
$this->gc->greeting_count),
$this->gc->greeting_count));
}
}
```
Return true if read only.
------------------
Some actions only read from the database; others read and write. The simple
database load-balancer built into GNU social will direct read-only actions to
database mirrors (if they are configured) and read-write actions to the master database.
This defaults to false to avoid data integrity issues, but you should make sure
to overload it for performance gains.
```php
function isReadOnly($args)
{
return false;
}
```

View File

@@ -1,112 +0,0 @@
# Contributing to GNU social
First of all, if you're reading this intending to contribute to GNU social,
thanks! Free software development only happens when people like you take an
interest in giving back to the software they themselves use, and their
community.
When contributing to this repository, please first discuss the change you wish to
make via issue, email, or any other method with the owners of this repository before
making a change.
There's a few files you should read before going forward with a merge request
or a patch submission. They detail what this file touches on in brief. They
are:
* `DOCUMENTATION/DEVELOPERS/CONTRIBUTING/coding_standards.md`: How your code should be structured and formatted to be
accepted into the GNU social codebase.
* `/DOCUMENTATION/DEVELOPERS/CONTRIBUTING/merge_request_checklist.md`: A quick checklist to review before submission.
## Merge Request Process
1. Run php-cs-fixer. We also recommend you to use tools like phpstan, phpactor, phpcs and phpmd
2. Run our unit tests (`./vendor/bin/phpunit --testsuite Core`)
3. Respect our [VERSIONING](https://notabug.org/diogo/gnu-social/src/nightly/DOCUMENTATION/VERSIONING.md) system
4. You may merge the Merge Request in once you have the sign-off of two other developers, or if you
do not have permission to do that, you may request the second reviewer to merge it for you
## Coding Standards
Since we will be expected to maintain your code once it's submitted, we ask you
to adhere to certain coding standards that make it easier for us to do so. If
code doesn't follow them, it will be rejected, so please read up on these.
## Bug Reports
Please report bugs to the issue tracker at
<https://notabug.org/diogo/gnu-social/issues> Avoid assigning the labels
yourself, as these are for the development team to assign priority and area of
coverage to a subject. Please only submit something here if you are certain it
is a bug or represents a feature enhancement that we do not presently have. If
you are uncertain whether it's a bug, please feel free to ask
at #social IRC channel on freenode.net https://www.freenode.net/.
When reporting a bug, please try to include as much information as possible,
including the environment being run on (if it's a common LAMP stack just give
us version numbers of the main stack components, that's fine), and the specific
error you get. If you do not get a client-facing error, please check the PHP
error_log and ensure there isn't something silently reported there, as well as
the GNU social log. Try to include steps to reproduce the error as well, as if
we cannot reproduce the error, we can't fix it!
It is perfectly acceptable to reference the archive page of a discussion on the
mailing list for the bug report, by the way, as long as it includes all the
information we need for a bug report.
## Submitting Feature Requests / Enhancement Requests
Social media is constantly evolving, and we welcome ideas about how we can
change and evolve GNU social to keep it the excellent piece of software that it
is. However, there are a few things we ask you do when submitting feature
requests:
1. Understand that since we have a limited amount of developers and these people
contribute in their free time, we may prioritize things differently than you
value them. Oftentimes this is because certain requests involve less changes
to the existing codebase than others, and therefore this makes them easier
to add.
2. Please search the existing feature requests and enhancements to see if a
similar request exists. If one does but you have different ideas about how
to do it or what it should entail, please add a comment to the existing idea
rather than create a new one for your "version" of it. Duplicate submissions
mean we spend more time maintaining the tracker and less time actually
working on the codebase!
3. When outlining the way that you see something working, don't be afraid to be
as detailed as possible! We may not implement it exactly as you describe for
any variety of reasons, but the more concrete and fleshed out an idea is, the
easier it is for us to know what you want and be able to implement it in a
sane and secure fashion.
4. When describing a possible new idea and its mechanisms of operation, the key
words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the issue submission
are to be interpreted as described in RFC 2119.
<https://tools.ietf.org/html/rfc2119>
Finally, and just as a call back to the first point, realize just because we
might not rush to implement something, doesn't mean that we don't want to
implement it! We would rather take the time to do something right the first
time, then hurriedly apply a new idea, or a fix, only to have to patch it later.
## Branch of Code Submissions
Unless you've been specifically directed otherwise, all submissions of code
should be against the `nightly` branch, so make sure any modifications are based
on Nightly.
## Copyright / Licensing
You acknowledge that by submitting code to GNU social, you are licensing it under
the GNU AGPLv3 unless there is an extenuating circumstance where it would be
licensed differently (such as modifications to an external library we include
such as Stomp).
You also acknowledge that unless you assign a copyright explicitly, it will be
assumed to be assigned to GNU social.
Thanks for considering submission, and happy hacking!

View File

@@ -0,0 +1,3 @@
In the `dev` environment, the default values for the config table are reloaded on each HTTP request
In case you want to override this, add `SOCIAL_NO_RELOAD_DEFAULTS=1` to your .env.local file

View File

@@ -0,0 +1 @@
../../INSTALL.md

File diff suppressed because it is too large Load Diff

View File

@@ -1,44 +0,0 @@
Plugins
=======
GNU social supports a simple but
powerful plugin architecture. Important events in the code are named,
like 'StartNoticeSave', and other software can register interest
in those events. When the events happen, the other software is called
and has a choice of accepting or rejecting the events.
In the simplest case, you can add a function to config.php and use the
Event::addHandler() function to hook an event:
function AddMyWebsiteLink($action)
{
$action->menuItem('http://mywebsite.net/', _('My web site'), _('Example web link'));
return true;
}
Event::addHandler('EndPrimaryNav', 'AddMyWebsiteLink');
This adds a menu item to the end of the main navigation menu. You can
see the list of existing events, and parameters that handlers must
implement, in EVENTS.txt.
The Plugin class in lib/plugin.php makes it easier to write more
complex plugins. Sub-classes can just create methods named
'onEventName', where 'EventName' is the name of the event (case
matters!). These methods will be automatically registered as event
handlers by the Plugin constructor (which you must call from your own
class's constructor).
Several example plugins are included in the plugins/ directory. You
can enable a plugin with the following line in config.php:
addPlugin('Example', array('param1' => 'value1',
'param2' => 'value2'));
This will look for and load files named 'ExamplePlugin.php' or
'Example/ExamplePlugin.php' either in the plugins/ directory (for
plugins that ship with GNU social) or in the local/ directory (for
plugins you write yourself or that you get from somewhere else) or
local/plugins/.
Plugins are documented in their own directories.

View File

@@ -0,0 +1 @@
../../INSTALL.md

View File

@@ -1,15 +0,0 @@
#Simple way to Webfinger enable your domain -- needs PHP
##Step 1
Put the 'dot-well-known' on your website, so it loads at:
https://another_cool.org/.well-known/
(Remember the . at the beginning of this one, which is common practice
for "hidden" files and why we have renamed it "dot-")
## Step 2
Edit the .well-known/webfinger/index.php file and replace "https://www.example.org/gnusocial/index.php" with the domain name
you're hosting the .well-known handler on.

View File

@@ -1,56 +0,0 @@
<?php
// FIXME: REPLACE \/ here
define('MY_GNUSOCIAL', 'https://www.example.org/gnusocial/index.php');
/**
* This is a general solution for when you can't have your GNU social instance in the domain root and for when you want to
* socialfy from another domain.
*/
// From https://www.php.net/manual/en/function.getallheaders.php#84262 (joyview at gmail dot com)
if (!function_exists('getallheaders')) {
function getallheaders()
{
$headers = [];
foreach ($_SERVER as $name => $value) {
if (substr($name, 0, 5) == 'HTTP_') {
$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
}
}
return $headers;
}
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, getallheaders());
curl_setopt($ch, CURLOPT_URL, MY_GNUSOCIAL . str_replace('webfinger/', 'webfinger', $_SERVER['REQUEST_URI']));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
$response = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$body = substr($response, $header_size);
// From https://stackoverflow.com/a/10590242 (c.hill)
function get_headers_from_curl_response($response)
{
$headers = array();
$header_text = substr($response, 0, strpos($response, "\r\n\r\n"));
foreach (explode("\r\n", $header_text) as $i => $line) {
if ($i === 0) {
$headers['http_code'] = $line;
} else {
list($key, $value) = explode(': ', $line);
$headers[$key] = $value;
}
}
return $headers;
}
$headers = get_headers_from_curl_response($response);
foreach ($headers as $name => $value) {
header("{$name}: $value");
}
echo $body;
curl_close($ch);

View File

@@ -1,100 +0,0 @@
Upgrading
=========
GNU social 1.1.x to GNU social 1.2.x
------------------------------------
If you are tracking the GNU social git repository, we currently recommend
using the "master" branch (or nightly if you want to use latest features)
and follow this procedure:
0. Backup your data. The StatusNet upgrade discussions below have some
guidelines to back up the database and files (mysqldump and rsync).
MAKE SURE YOU ARE THE SAME USER THAT RUNS THE PHP FILES WHILE PERFORMING
THE COMMANDS BELOW (I usually prepend the commands with 'sudo -u social')
1. Stop your queue daemons (you can run this command even if you do not
use the queue daemons):
$ bash scripts/stopdaemons.sh
2. Run the command to fetch the latest sourcecode:
$ git pull
If you are not using git we recommend following the instructions below
for upgrading "StatusNet 1.1.x to GNU social 1.2.x" as they are similar.
3. Run the upgrade script:
$ php scripts/upgrade.php
The upgrade script will likely take a long time because it will
upgrade the tables to another character encoding and make other
automated upgrades. Make sure it ends without errors. If you get
errors, create a new task on https://git.gnu.io/gnu/gnu-social/issues
4. Start your queue daemons again (you can run this command even if you
do not use the queue daemons):
$ bash scripts/startdaemons.sh
5. Report any issues at https://git.gnu.io/gnu/gnu-social/issues
If you are using ssh keys to log in to your server, you can make this
procedure pretty painless (assuming you have automated backups already).
Make sure you "cd" into the correct directory (in this case "htdocs")
and use the correct login@hostname combo:
$ ssh social@domain.example 'cd htdocs
&& bash scripts/stopdaemons.sh
&& git pull
&& time php scripts/upgrade.php
&& bash scripts/startdaemons.sh'
StatusNet 1.1.x to GNU social 1.2.x
-----------------------------------
We cannot support migrating from any other version of StatusNet than
1.1.1. If you are running a StatusNet version lower than this, please
follow the upgrade procedures for each respective StatusNet version.
You are now running StatusNet 1.1.1 and want to migrate to GNU social
1.2.x. Beware there may be changes in minimum required version of PHP
and the modules required, so review the INSTALL file (php5-intl is a
newly added dependency for example).
* Before you begin: Make backups. Always make backups. Of your entire
directory structure and the database too. All tables. All data. Alles.
0. Make a backup of everything. To backup the database, you can use a
variant of this command (you will be prompted for the database password):
$ mysqldump -u dbuser -p dbname > social-backup.sql
1. Stop your queue daemons 'bash scripts/stopdaemons.sh' should do it.
Not everyone runs queue daemons, but the above command won't hurt.
2. Unpack your GNU social code to a fresh directory. You can do this
by cloning our git repository:
$ git clone https://git.gnu.io/gnu/gnu-social.git gnusocial
3. Synchronize your local files to the GNU social directory. These
will be the local files such as avatars, config and files:
avatar/*
file/*
local/*
.htaccess
config.php
This command will point you in the right direction on how to do it:
$ rsync -avP statusnet/{.htaccess,avatar,file,local,config.php} gnusocial/
4. Replace your old StatusNet directory with the new GNU social
directory in your webserver root.
5. Run the upgrade script: 'php scripts/upgrade.php'
The upgrade script will likely take a long time because it will
upgrade the tables to another character encoding and make other
automated upgrades. Make sure it ends without errors. If you get
errors, create a new task on https://git.gnu.io/gnu/gnu-social/issues
6. Start your queue daemons: 'bash scripts/startdaemons.sh'
7. Report any issues at https://git.gnu.io/gnu/gnu-social/issues

View File

@@ -1,60 +0,0 @@
### GNU social "fancy URL" setup
#
# Change the "RewriteBase" in the new .htaccess file to be the URL path
# to your GNU Social installation on your server. Typically this will
# be the path to your GNU Social directory relative to your Web root.
# If you are installing it in the root directory, leave it as '/'.
#
# If it doesn't work, double-check that AllowOverride for the GNU Social
# directory is 'All' in your Apache configuration file. This can be
# * /etc/apache2/apache2.conf (generic)
# * /etc/apache2/sites-available/default(on Debian and Ubuntu)
# * ...many other variations depending on distribution...
#
# See the Apache documentation for .htaccess files for more details:
# https://httpd.apache.org/docs/2.4/howto/htaccess.html
#
# Also, check that mod_rewrite is installed and enabled:
# https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html
<IfModule mod_rewrite.c>
RewriteEngine On
# NOTE: change this to your actual GNU social base URL path,
# minus the domain part:
#
# https://social.example.com/ => /
# https://example.com/social/ => /social/
#
RewriteBase /
#RewriteBase /mublog/
## Uncomment these if having trouble with API authentication
## when PHP is running in CGI or FastCGI mode.
#
#RewriteCond %{HTTP:Authorization} ^(.*)
#RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?p=$1 [L,QSA]
## You can also use PATHINFO by using this RewriteRule instead:
# RewriteRule (.*) index.php/$1 [L,QSA]
</IfModule>
# Enable X-Sendfile if available. Still needs to be enabled in the config
<IfModule mod_xsendfile.c>
XSendFile On
</IfModule>
<FilesMatch "\.(ini)">
<IfVersion < 2.3>
Order allow,deny
Deny from all
</IfVersion>
<IfVersion >= 2.3>
Require all denied
</IfVersion>
</FilesMatch>

View File

@@ -1,28 +0,0 @@
# This is completely optional, but if you're running a site with
# ssl="always" configured, then you might as well redirect any of
# your stray HTTP visitors to HTTPS.
#
#$HTTP["scheme"] == "http" {
# $HTTP["host"] =~ "^(social\.example\.com)$" {
# url.redirect = ( "^\/?(.*)" => "https://%1/$1" )
# server.name = "%1"
# }
#}
# If you're using vhosts, you should have per-vhost server.document-root
# settings too! Read how in the respective alternative vhost modules.
#$HTTP["host"] =~ "^social\.example\.com$" {
# NOTE: configure fastcgi/cgi/fpm here if you're using per-user cgi/fpm
# fastcgi.server += ( ".php" =>
# ( "localhost" => (
# "host" => "127.0.0.1",
# "port" => "9000"
# ))
# )
dir-listing.activate = "disable"
# Make sure "mod_rewrite" is enabled in server.modules
url.rewrite-if-not-file = ( "^/(.*)$" => "/index.php/$1" )
#}

View File

@@ -1,97 +0,0 @@
server {
listen [::]:80;
listen 80;
# FIXME: Change domain name here (and also make sure you do the same in the next 'server' section)
server_name social.example.org;
# redirect all traffic to HTTPS
rewrite ^ https://$host$request_uri? permanent;
}
server {
# HTTPS is mandatory on GNU social unless you are using Tor network. Seriously.
# Set it up with a cert (any cert) before you run the install.
listen [::]:443 ssl http2;
listen 443 ssl http2;
# Root
# FIXME: Change the path below to where you installed GNU social (GNU social's root + /public)
root /var/www/gnusocial/public;
# Server name
# FIXME: Change "social.example.org" to your site's domain name
server_name social.example.org;
# SSL
# FIXME: Change the paths to setup your SSL key/cert. See https://cipherli.st/ for more information
ssl_certificate ssl/certs/social.example.org.crt;
ssl_certificate_key ssl/private/social.example.org.key;
# Index
index index.php;
# X-Accel/X-Sendfile. Still needs to be enabled in the config
location /file {
internal;
# FIXME: Change "/path/to/gnusocial/root/" to the folder where
# attachments are stored (normally the same as the site root)
root /path/to/gnusocial/root/;
}
# PHP
location ~ ^/(index|install)\.php(/.*)?$ {
#location ^~ /index.php {
include fastcgi_params;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
# Don't allow any PHP file other than index.php to be executed
# This will ensure that nor config.php nor plugin files with eventual hardcoded security information are downloadable
# And this is better than allowing php files to be executed in case of forgotten `if (!defined('GNUSOCIAL')) { exit(1); }`
location ~ \.php$ {
deny all;
}
# Location
location / {
try_files $uri $uri/ @index_handler;
}
# Fancy URLs
error_page 404 @index_handler;
location @index_handler {
rewrite ^(.*)$ /index.php?p=$1 last;
}
# Restrict access that is unnecessary anyway
location ~ /\.(ht|git) {
deny all;
}
#
# Hardening (optional)
#
# add_header Strict-Transport-Security "max-age=15768000; preload;";
# add_header X-Content-Type-Options nosniff;
# add_header Referrer-Policy strict-origin-when-cross-origin;
# add_header Content-Security-Policy "default-src 'self' 'unsafe-inline'; frame-ancestors 'self'; form-action 'self'; style-src 'self' 'unsafe-inline'; img-src * blob: data:;";
# add_header X-Permitted-Cross-Domain-Policies none;
# add_header X-Robots-Tag all; # Not really hardening, just here for strictness purposes
#
# client_max_body_size 15M;
# client_body_buffer_size 128k;
# gzip_vary on;
#
# location ~* \.(?:css|js|woff|svg|gif|png|webp|ttf|ico|jpe?g)$ {
# gzip on;
# gzip_comp_level 4;
# add_header Cache-Control "public";
# expires 30d;
# access_log off;
# log_not_found off;
# }
}

View File

@@ -1,17 +0,0 @@
# Versioning
## Release cycle
We follow Semantic Versioning as defined on [https://semver.org/](https://semver.org).
The GNU social platform has a monthly release cycle. That is, we only increment the version number on day 1 of each month.
For GNU social plugins, we increment version number by commit. Plugins update have a propagation of the same type in the
GNU social's monthly version bump.
If we have various patch type updates in a month, we only bump it by one in the end of the month. If in the same month
we have a minor too, we will only bump the minor value.
# Lifecycle
GNU social has 'dev', 'alpha', 'beta', 'rc' and 'release' cycles. We usually are in `dev` during summer. When we finish a `dev` cycle we release an `alpha` (`dev`s aren't tagged as releases). From `alpha` to `release` it depends on how perfect GNU social is after the end of the `dev` cycle. But we use the number after `alpha` instead of `patch` number for small bug fixes when in this cycle. When we finally go from a `r`elease `c`andidate to a `release`, we party... and we use semver for all the small changes until we start working in another `dev` cycle (usually on another summer).

View File

@@ -1,463 +1,5 @@
TABLE OF CONTENTS
=================
* Prerequisites
- PHP modules
- Better performance
* Installation
- Getting it up and running
- Fancy URLs
- Themes
- Private
* Extra features
- Sphinx
- SMS
- Translation
- Queues and daemons
* After installation
- Backups
- Upgrading
* Additional configuration
GNU social
=====
Prerequisites
=============
PHP modules
-----------
The following software packages are *required* for this software to
run correctly.
- PHP 7+ PHP7.x is also supported.
- MariaDB 5+ MariaDB 10.x is also supported.
- Web server Apache, lighttpd and nginx will all work. CGI mode is
recommended and also some variant of 'suexec' (or a
proper setup php-fpm pool)
NOTE: mod_rewrite or its equivalent is extremely useful.
Your PHP installation must include the following PHP extensions for a
functional setup of GNU social:
- openssl (compiled in for Debian, enabled manually in Arch Linux)
- php-curl Fetching files by HTTP.
- php-exif Exchangeable image information.
- php-gd Image manipulation (scaling).
- php-intl Internationalization support (transliteration et al).
- php-json For WebFinger lookups and more.
- php-mbstring String manipulation
- php-mysql The native driver for MariaDB connections.
- php-gmp For Salmon signatures (part of OStatus)
- php-bcmath Arbitrary Precision Mathematics
- php-opcache Improved PHP performance by precompilation
- php-readline For interactive scripts
- php-xml XML parser
- php-ds Faster data structures
NOTE: Some distros require manual enabling in the relevant php.ini for some modules.
Better performance
------------------
For some functionality, you will also need the following extensions:
- opcache Improves performance a _lot_. Included in PHP, must be
enabled manually in php.ini for most distributions. Find
and set at least: opcache.enable=1
- mailparse Efficient parsing of email requires this extension.
Submission by email or SMS-over-email uses this.
- sphinx A client for the sphinx server, an alternative to MySQL
or Postgresql fulltext search. You will also need a
Sphinx server to serve the search queries.
- gettext For multiple languages. Default on many PHP installs;
will be emulated if not present.
- exif For thumbnails to be properly oriented.
- php-ds For faster data structures; will be emulated if not present.
You may also experience better performance from your site if you configure
a PHP cache/accelerator. Most distributions come with "opcache" support.
Enable it in your php.ini where it is documented together with its settings.
Installation
============
Getting it up and running
-------------------------
Installing the basic GNU Social web component is relatively easy,
especially if you've previously installed PHP/MariaDB packages.
1. Unpack the tarball you downloaded on your Web server. Usually a
command like this will work:
tar zxf gnusocial-*.tar.gz
...which will make a gnusocial-x.y.z subdirectory in your current
directory. (If you don't have shell access on your Web server, you
may have to unpack the tarball on your local computer and FTP the
files to the server.)
2. Move the tarball to a directory of your choosing in your Web root
directory. Usually something like this will work:
mv gnusocial-x.y.z /var/www/gnusocial
This will often make your GNU Social instance available in the gnusocial
path of your server, like "http://example.net/gnusocial". "social" or
"blog" might also be good path names. If you know how to configure
virtual hosts on your web server, you can try setting up
"http://social.example.net/" or the like.
If you have "rewrite" support on your webserver, and you should,
then please enable this in order to make full use of your site. This
will enable "Fancy URL" support, which you can read more about if you
scroll down a bit in this document.
3. Make your target directory writeable by the Web server, please note
however that 'a+w' will give _all_ users write access and securing the
webserver is not within the scope of this document.
chmod a+w /var/www/gnusocial/
On some systems, this will work as a more secure alternative:
chgrp www-data /var/www/gnusocial/
chmod g+w /var/www/gnusocial/
If your Web server runs as another user besides "www-data", try
that user's default group instead. As a last resort, you can create
a new group like "gnusocial" and add the Web server's user to the group.
4. Create a database to hold your site data. Something like this
should work (you will be prompted for your database password):
mysqladmin -u "root" -p create social
Note that GNU Social should have its own database; you should not share
the database with another program. You can name it whatever you want,
though.
(If you don't have shell access to your server, you may need to use
a tool like phpMyAdmin to create a database. Check your hosting
service's documentation for how to create a new MariaDB database.)
5. Create a new database account that GNU Social will use to access the
database. If you have shell access, this will probably work from the
MariaDB shell:
GRANT ALL on social.*
TO 'social'@'localhost'
IDENTIFIED BY 'agoodpassword';
You should change the user identifier 'social' and 'agoodpassword'
to your preferred new database username and password. You may want to
test logging in to MariaDB as this new user.
6. In a browser, navigate to the GNU Social install script; something like:
https://social.example.net/install.php
Enter the database connection information and your site name. The
install program will configure your site and install the initial,
almost-empty database.
7. You should now be able to navigate to your social site's main directory
and see the "Public Timeline", which will probably be empty. You can
now register new user, post some notices, edit your profile, etc.
Fancy URLs
----------
By default, GNU Social will use URLs that include the main PHP program's
name in them. For example, a user's home profile might be found at either
of these URLS depending on the webserver's configuration and capabilities:
https://social.example.net/index.php/fred
https://social.example.net/index.php?p=fred
It's possible to configure the software to use fancy URLs so it looks like
this instead:
https://social.example.net/fred
These "fancy URLs" are more readable and memorable for users. To use
fancy URLs, you must either have Apache 2.x with .htaccess enabled and
mod_rewrite enabled, -OR- know how to configure "url redirection" in
your server (like lighttpd or nginx).
1. See the instructions for each respective webserver software:
* For Apache, inspect the "htaccess.sample" file and save it as
".htaccess" after making any necessary modifications. Our sample
file is well commented.
* For lighttpd, inspect the lighttpd.conf.example file and apply the
appropriate changes in your virtualhost configuration for lighttpd.
* For nginx, inspect the nginx.conf.sample file and apply the appropriate
changes.
* For other webservers, we gladly accept contributions of
server configuration examples.
2. Assuming your webserver is properly configured and have its settings
applied (remember to reload/restart it), you can add this to your
GNU social's config.php file:
$config['site']['fancy'] = true;
You should now be able to navigate to a "fancy" URL on your server,
like:
https://social.example.net/main/register
Themes
------
As of right now, your ability change the theme is limited to CSS
stylesheets and some image files; you can't change the HTML output,
like adding or removing menu items, without the help of a plugin.
You can choose a theme using the $config['site']['theme'] element in
the config.php file. See below for details.
You can add your own theme by making a sub-directory of the 'theme'
subdirectory with the name of your theme. Each theme can have the
following files:
display.css: a CSS2 file for "default" styling for all browsers.
logo.png: a logo image for the site.
default-avatar-profile.png: a 96x96 pixel image to use as the avatar for
users who don't upload their own.
default-avatar-stream.png: Ditto, but 48x48. For streams of notices.
default-avatar-mini.png: Ditto ditto, but 24x24. For subscriptions
listing on profile pages.
You may want to start by copying the files from the default theme to
your own directory.
Private
-------
A GNU social node can be configured as "private", which means it will not
federate with other nodes in the network. It is not a recommended method
of using GNU social and we cannot at the current state of development
guarantee that there are no leaks (what a public network sees as features,
private sites will likely see as bugs).
Private nodes are however an easy way to easily setup collaboration and
image sharing within a workgroup or a smaller community where federation
is not a desired feature. Also, it is possible to change this setting and
instantly gain full federation features.
Access to file attachments can also be restricted to logged-in users only:
1. Add a directory outside the web root where your file uploads will be
stored. Use this command as an initial guideline to create it:
mkdir /var/www/gnusocial-files
2. Make the file uploads directory writeable by the web server. An
insecure way to do this is (to do it properly, read up on UNIX file
permissions and configure your webserver accordingly):
chmod a+x /var/www/gnusocial-files
3. Tell GNU social to use this directory for file uploads. Add a line
like this to your config.php:
$config['attachments']['dir'] = '/var/www/gnusocial-files';
Extra features
==============
Sphinx
------
To use a Sphinx server to search users and notices, you'll need to
enable the SphinxSearch plugin. Add to your config.php:
addPlugin('SphinxSearch');
$config['sphinx']['server'] = 'searchhost.local';
You also need to install, compile and enable the sphinx pecl extension for
php on the client side, which itself depends on the sphinx development files.
See plugins/SphinxSearch/README for more details and server setup.
SMS
---
StatusNet supports a cheap-and-dirty system for sending update messages
to mobile phones and for receiving updates from the mobile. Instead of
sending through the SMS network itself, which is costly and requires
buy-in from the wireless carriers, it simply piggybacks on the email
gateways that many carriers provide to their customers. So, SMS
configuration is essentially email configuration.
Each user sends to a made-up email address, which they keep a secret.
Incoming email that is "From" the user's SMS email address, and "To"
the users' secret email address on the site's domain, will be
converted to a notice and stored in the DB.
For this to work, there *must* be a domain or sub-domain for which all
(or most) incoming email can pass through the incoming mail filter.
1. Run the SQL script carrier.sql in your StatusNet database. This will
usually work:
mysql -u "statusnetuser" --password="statusnetpassword" statusnet < db/carrier.sql
This will populate your database with a list of wireless carriers
that support email SMS gateways.
2. Make sure the maildaemon.php file is executable:
chmod +x scripts/maildaemon.php
Note that "daemon" is kind of a misnomer here; the script is more
of a filter than a daemon.
2. Edit /etc/aliases on your mail server and add the following line:
*: /path/to/statusnet/scripts/maildaemon.php
3. Run whatever code you need to to update your aliases database. For
many mail servers (Postfix, Exim, Sendmail), this should work:
newaliases
You may need to restart your mail server for the new database to
take effect.
4. Set the following in your config.php file:
$config['mail']['domain'] = 'yourdomain.example.net';
Translations
------------
For info on helping with translations, see the platform currently in use
for translations: https://www.transifex.com/projects/p/gnu-social/
Translations use the gettext system <http://www.gnu.org/software/gettext/>.
If you for some reason do not wish to sign up to the Transifex service,
you can review the files in the "locale/" sub-directory of GNU social.
Each plugin also has its own translation files.
To get your own site to use all the translated languages, and you are
tracking the git repo, you will need to install at least 'gettext' on
your system and then run:
$ make translations
Queues and daemons
------------------
Some activities that StatusNet needs to do, like broadcast OStatus, SMS,
XMPP messages and TwitterBridge operations, can be 'queued' and done by
off-line bots instead.
Two mechanisms are available to achieve offline operations:
* New embedded OpportunisticQM plugin, which is enabled by default
* Legacy queuedaemon script, which can be enabled via config file.
### OpportunisticQM plugin
This plugin is enabled by default. It tries its best to do background
jobs during regular HTTP requests, like API or HTML pages calls.
Since queueing system is enabled by default, notices to be broadcasted
will be stored, by default, into DB (table queue_item).
Whenever it has time, OpportunisticQM will try to handle some of them.
This is a good solution whether you:
* have no access to command line (shared hosting)
* do not want to deal with long-running PHP processes
* run a low traffic GNU social instance
In other case, you really should consider enabling the queuedaemon for
performance reasons. Background daemons are necessary anyway if you wish
to use the Instant Messaging features such as communicating via XMPP.
### queuedaemon
If you want to use legacy queuedaemon, you must be able to run
long-running offline processes, either on your main Web server or on
another server you control. (Your other server will still need all the
above prerequisites, with the exception of Apache.) Installing on a
separate server is probably a good idea for high-volume sites.
1. You'll need the "CLI" (command-line interface) version of PHP
installed on whatever server you use.
Modern PHP versions in some operating systems have disabled functions
related to forking, which is required for daemons to operate. To make
this work, make sure that your php-cli config (/etc/php5/cli/php.ini)
does NOT have these functions listed under 'disable_functions':
* pcntl_fork, pcntl_wait, pcntl_wifexited, pcntl_wexitstatus,
pcntl_wifsignaled, pcntl_wtermsig
Other recommended settings for optimal performance are:
* mysqli.allow_persistent = On
* mysqli.reconnect = On
2. If you're using a separate server for queues, install StatusNet
somewhere on the server. You don't need to worry about the
.htaccess file, but make sure that your config.php file is close
to, or identical to, your Web server's version.
3. In your config.php files (on the server where you run the queue
daemon), set the following variable:
$config['queue']['daemon'] = true;
You may also want to look at the 'Queues and Daemons' section in
this file for more background processing options.
4. On the queues server, run the command scripts/startdaemons.sh.
This will run the queue handlers:
* queuedaemon.php - polls for queued items for inbox processing and
pushing out to OStatus, SMS, XMPP, etc.
* imdaemon.php - if an IM plugin is enabled (like XMPP)
* other daemons, like TwitterBridge ones, that you may have enabled
These daemons will automatically restart in most cases of failure
including memory leaks (if a memory_limit is set), but may still die
or behave oddly if they lose connections to the XMPP or queue servers.
It may be a good idea to use a daemon-monitoring service, like 'monit',
to check their status and keep them running.
All the daemons write their process IDs (pids) to /var/run/ by
default. This can be useful for starting, stopping, and monitoring the
daemons. If you are running multiple sites on the same machine, it will
be necessary to avoid collisions of these PID files by setting a site-
specific directory in config.php:
$config['daemon']['piddir'] = __DIR__ . '/../run/';
It is also possible to use a STOMP server instead of our kind of hacky
home-grown DB-based queue solution. This is strongly recommended for
best response time, especially when using XMPP.
After installation
==================
Backups
-------
There is no built-in system for doing backups in GNU social. You can make
backups of a working StatusNet system by backing up the database and
the Web directory. To backup the database use mysqldump <https://mariadb.com/kb/en/mariadb/mysqldump/>
and to backup the Web directory, try tar.
Upgrading
---------
Upgrading is strongly recommended to stay up to date with security fixes
and new features. For instructions on how to upgrade GNU social code,
please see the UPGRADE file.
Additional configuration
------------------------
Please refer to DOCUMENTATION/SYSTEM_ADMINISTRATORS/CONFIGURE for information.
GNU social is a federated social network. For documentation, visit
https://docs.gnusocial.rocks/ or view the files under docs/

127
Makefile
View File

@@ -1,21 +1,122 @@
# Warning: do not transform tabs to spaces in this file.
all : translations
DIR=$(strip $(notdir $(CURDIR))) # Seems a bit hack-ish, but `basename` works differently
core_mo = $(patsubst %.po,%.mo,$(wildcard locale/*/LC_MESSAGES/statusnet.po))
plugin_mo = $(patsubst %.po,%.mo,$(wildcard plugins/*/locale/*/LC_MESSAGES/*.po))
translate-container-name = $$(if docker container inspect $(1) > /dev/null 2>&1; then echo $(1); else echo $(1) | sed 'y/_/-/' ; fi)
args = `arg="$(filter-out $@,$(MAKECMDGOALS))" && echo $${arg:-${1}}`
translations : $(core_mo) $(plugin_mo)
%:
@:
upgrade :
php scripts/upgrade.php
.PHONY:
@if ! docker info > /dev/null; then echo "Docker does not seem to be running"; exit 1; fi
clean :
rm -f $(core_mo) $(plugin_mo)
up: .PHONY
docker-compose up -d
updatepo :
php scripts/update_po_templates.php --all
down: .PHONY
docker-compose down
%.mo : %.po
msgfmt -o $@ $<
redis-shell:
docker exec -it $(call translate-container-name,$(strip $(DIR))_redis_1) sh -c 'redis-cli'
php-repl: .PHONY
docker exec -it $(call translate-container-name,$(strip $(DIR))_php_1) sh -c '/var/www/social/bin/console psysh'
php-shell: .PHONY
docker exec -it $(call translate-container-name,$(strip $(DIR))_php_1) sh -c 'cd /var/www/social; sh'
psql-shell: .PHONY
docker exec -it $(call translate-container-name,$(strip $(DIR))_db_1) sh -c "psql -U postgres social"
database-force-nuke:
docker stop $(call translate-container-name,$(strip $(DIR))_worker_1) \
&& docker exec -it $(call translate-container-name,$(strip $(DIR))_php_1) sh -c "cd /var/www/social; bin/console doctrine:database:drop --force && bin/console doctrine:database:create && bin/console doctrine:schema:update --dump-sql --force && bin/console app:populate_initial_values" \
&& docker-compose up -d
database-force-schema-update:
docker exec -it $(call translate-container-name,$(strip $(DIR))_php_1) sh -c "/var/www/social/bin/console doctrine:schema:update --dump-sql --force"
tooling-docker: .PHONY
@cd docker/tooling && docker-compose up -d --build > /dev/null 2>&1
stop-tooling: .PHONY
cd docker/tooling && docker-compose down
tooling-php-shell: tooling-docker
docker exec -it $(call translate-container-name,tooling_php_1) sh
test-accesibility: tooling-docker
cd docker/tooling && docker-compose run pa11y /accessibility.sh
test: tooling-docker
docker exec $(call translate-container-name,tooling_php_1) /var/tooling/coverage.sh $(call args,'')
cs-fixer: tooling-docker
@bin/php-cs-fixer $${CS_FIXER_FILE}
doc-check: tooling-docker
bin/php-doc-check
phpstan: tooling-docker
bin/phpstan
remove-var:
rm -rf var/*
remove-file:
sudo rm -rf file/*
flush-redis-cache:
docker exec -it $(call translate-container-name,$(strip $(DIR))_redis_1) sh -c 'redis-cli flushall'
install-plugins:
docker exec -it $(call translate-container-name,$(strip $(DIR))_php_1) /var/www/social/bin/install_plugins.sh
update-dependencies:
docker exec -it $(call translate-container-name,$(strip $(DIR))_php_1) sh -c 'cd /var/www/social && composer update'
update-autocode:
docker exec -it $(call translate-container-name,$(strip $(DIR))_php_1) sh -c 'cd /var/www/social && bin/update_autocode'
backup-actors:
docker exec -it $(call translate-container-name,$(strip $(DIR))_db_1) \
sh -c 'su postgres -c "mkdir -p /tmp/backup"' && \
docker exec -it $(call translate-container-name,$(strip $(DIR))_php_1) \
sh -c "cd /var/www/social && bin/console doctrine:query:sql \"\
copy actor to '/tmp/backup/actor.csv';\
copy local_user to '/tmp/backup/local_user.csv';\
copy local_group to '/tmp/backup/local_group.csv';\
\
copy activitypub_actor to '/tmp/backup/ap_actor.csv';\
copy activitypub_rsa to '/tmp/backup/ap_rsa.csv';\
\
copy actor_subscription to '/tmp/backup/actor_subscription.csv';\
copy group_member to '/tmp/backup/group_member.csv';\
\
copy feed to '/tmp/backup/feed.csv';\
copy (SELECT 'ALTER SEQUENCE ' || c.relname || ' RESTART WITH ' || nextval(c.relname::regclass) || ';'\
FROM pg_class c WHERE c.relkind = 'S') to '/tmp/backup/sequences';\"" && \
mkdir -p /tmp/social-sql-backup && \
docker cp $(call translate-container-name,$(strip $(DIR))_db_1):/tmp/backup/. /tmp/social-sql-backup
restore-actors:
docker cp /tmp/social-sql-backup/. $(call translate-container-name,$(strip $(DIR))_db_1):/tmp/backup
docker exec -it $(call translate-container-name,$(strip $(DIR))_db_1) sh -c 'chown postgres /tmp/backup' && \
docker exec -it $(call translate-container-name,$(strip $(DIR))_php_1) \
sh -c "cd /var/www/social && bin/console doctrine:query:sql \"\
copy actor from '/tmp/backup/actor.csv';\
copy local_user from '/tmp/backup/local_user.csv';\
copy local_group from '/tmp/backup/local_group.csv';\
\
copy activitypub_actor from '/tmp/backup/ap_actor.csv';\
copy activitypub_rsa from '/tmp/backup/ap_rsa.csv';\
\
copy actor_subscription from '/tmp/backup/actor_subscription.csv';\
copy group_member from '/tmp/backup/group_member.csv';\
\
copy feed from '/tmp/backup/feed.csv';\
`cat /tmp/social-sql-backup/sequences`\""
force-nuke-everything: down remove-var remove-file up flush-redis-cache database-force-nuke install-plugins
force-delete-content: backup-actors force-nuke-everything restore-actors

157
README.md
View File

@@ -1,157 +0,0 @@
# GNU social 2.0.x
(c) 2010-2019 Free Software Foundation, Inc
This is the README file for GNU social, the free
software social networking platform. It includes
general information about the software and the
project.
The file INSTALL.md has useful instructions on how to
install this software.
System administrators may find the `DOCUMENTATION/SYSTEM_ADMINISTRATORS`
directory useful, namely:
- upgrade_from: upgrading from different software
- CONFIGURE.md: configuration options in gruesome detail.
- PLUGINS.md: how to install and configure plugins.
Developers may find the `DOCUMENTATION/DEVELOPERS` directory useful.
## About
GNU social is a free social networking
platform. It helps people in a community, company
or group to exchange short status updates, do
polls, announce events, or other social activities
(and you can add more!). Users can choose which
people to "follow" and receive only their friends'
or colleagues' status messages. It provides a
similar service to proprietary social network sites,
but is much more awesome.
With a little work, status messages can be sent to
mobile phones, instant messenger programs (using
XMPP), and specially-designed desktop clients that
support the Twitter API.
GNU social supports open standards (such as OStatus
<https://www.w3.org/community/ostatus/>) that lets users in
different networks follow each other. It enables a
distributed social network spread all across the
Web.
GNU social was originally developed as "StatusNet" by
StatusNet, Inc. with Evan Prodromou as lead developer.
It is shared with you in hope that you too make an
service available to your users. To learn more,
please see the Open Software Service Definition
1.1: <http://www.opendefinition.org/ossd>
### License
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 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
Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public
License along with this program, in the file "COPYING". If not, see
<http://www.gnu.org/licenses/>.
IMPORTANT NOTE: The GNU Affero General Public License (AGPL) has
*different requirements* from the "regular" GPL. In particular, if
you make modifications to the GNU social source code on your server,
you *MUST MAKE AVAILABLE* the modified version of the source code
to your users under the same license. This is a legal requirement
of using the software, and if you do not wish to share your
modifications, *YOU MAY NOT INSTALL GNU SOCIAL*.
Documentation in the /doc-src/ directory is available under the
Creative Commons Attribution 3.0 Unported license, with attribution to
"GNU social". See <http://creativecommons.org/licenses/by/3.0/> for details.
CSS and images in the /theme/ directory are available under the
Creative Commons Attribution 3.0 Unported license, with attribution to
"GNU social". See <http://creativecommons.org/licenses/by/3.0/> for details.
Our understanding and intention is that if you add your own theme that
uses only CSS and images, those files are not subject to the copyleft
requirements of the Affero General Public License 3.0. See
<http://wordpress.org/news/2009/07/themes-are-gpl-too/>. This is not
legal advice; consult your lawyer.
Additional library software has been made available in the 'extlib'
directory. All of it is Free Software and can be distributed under
liberal terms, but those terms may differ in detail from the AGPL's
particulars. See each package's license file in the extlib directory
for additional terms.
Refer to COPYING.md for full text of the software license..
### Troubleshooting
The primary output for GNU social is syslog,
unless you configured a separate logfile. This is
probably the first place to look if you're getting
weird behaviour from GNU social.
If you're tracking the unstable version of
GNU social in the git repository (see below), and you
get a compilation error ("unexpected T_STRING") in
the browser, check to see that you don't have any
conflicts in your code.
### Unstable version
If you're adventurous or impatient, you may want
to install the development version of GNU social.
To get it, use the git version control tool
<http://git-scm.com/> like so:
git clone git@notabug.org:diogo/gnu-social.git
In the current phase of development it is probably
recommended to use git as a means to stay up to date
with the source code. You can choose between these
branches:
* 1.20.x "oldstable", few updates, well tested coded
* master "stable", usually working well
* nightly "testing", most updates, not always working as expected
To keep it up-to-date, use `git pull`. Watch for conflicts!
As in any upgrade, do __not__ forget to run `/scripts/upgrade.php`.
## Further information
There are several ways to get more information about GNU social.
* The #social IRC channel on freenode.net <https://www.freenode.net/>.
* The unofficial XMPP room linked to IRC on <xmpp:gnusocial@conference.bka.li>
* The GNU social website <https://gnu.io/social/>
* GNU social has a bug tracker for any defects you may find, or ideas for
making things better. <https://notabug.org/diogo/gnu-social/issues>
* Patches are welcome, preferrably to our repository on notabug.org. <https://notabug.org/diogo/gnu-social>
## Credits
An incomplete list of developers who've worked on GNU social,
or its predecessors StatusNet and Free Social has been made available
in `CREDITS.md`.
### Current team
* Matt Lee
* Mikael Nordfeldth
* Diogo Cordeiro
* Bruno Casteleiro
* Miguel Dantas
* Alexei Sorokin

View File

@@ -1,214 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Site access administration panel
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Settings
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Administer site access settings
*
* @category Admin
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class AccessadminpanelAction extends AdminPanelAction
{
/**
* Returns the page title
*
* @return string page title
*/
function title()
{
// TRANS: Page title for Access admin panel that allows configuring site access.
return _('Access');
}
/**
* Instructions for using this form.
*
* @return string instructions
*/
function getInstructions()
{
// TRANS: Page notice.
return _('Site access settings');
}
/**
* Show the site admin panel form
*
* @return void
*/
function showForm()
{
$form = new AccessAdminPanelForm($this);
$form->show();
return;
}
/**
* Save settings from the form
*
* @return void
*/
function saveSettings()
{
static $booleans = array('site' => array('private', 'inviteonly', 'closed'),
'public' => array('localonly'));
foreach ($booleans as $section => $parts) {
foreach ($parts as $setting) {
$values[$section][$setting] = ($this->boolean($setting)) ? 1 : 0;
}
}
$config = new Config();
$config->query('BEGIN');
foreach ($booleans as $section => $parts) {
foreach ($parts as $setting) {
Config::save($section, $setting, $values[$section][$setting]);
}
}
$config->query('COMMIT');
return;
}
}
class AccessAdminPanelForm extends AdminForm
{
/**
* ID of the form
*
* @return int ID of the form
*/
function id()
{
return 'form_site_admin_panel';
}
/**
* class of the form
*
* @return string class of the form
*/
function formClass()
{
return 'form_settings';
}
/**
* Action of the form
*
* @return string URL of the action
*/
function action()
{
return common_local_url('accessadminpanel');
}
/**
* Data elements of the form
*
* @return void
*/
function formData()
{
$this->out->elementStart('fieldset', array('id' => 'settings_admin_account_access'));
// TRANS: Form legend for registration form.
$this->out->element('legend', null, _('Registration'));
$this->out->elementStart('ul', 'form_data');
$this->li();
// TRANS: Checkbox instructions for admin setting "Invite only".
$instructions = _('Make registration invitation only.');
// TRANS: Checkbox label for configuring site as invite only.
$this->out->checkbox('inviteonly', _('Invite only'),
(bool) $this->value('inviteonly'),
$instructions);
$this->unli();
$this->li();
// TRANS: Checkbox instructions for admin setting "Closed" (no new registrations).
$instructions = _('Disable new registrations.');
// TRANS: Checkbox label for disabling new user registrations.
$this->out->checkbox('closed', _('Closed'),
(bool) $this->value('closed'),
$instructions);
$this->unli();
$this->out->elementEnd('ul');
$this->out->elementEnd('fieldset');
// Public access settings (login requirements for feeds etc.)
$this->out->elementStart('fieldset', array('id' => 'settings_admin_public_access'));
// TRANS: Form legend for registration form.
$this->out->element('legend', null, _('Feed access'));
$this->out->elementStart('ul', 'form_data');
$this->li();
// TRANS: Checkbox instructions for admin setting "Private".
$instructions = _('Prohibit anonymous users (not logged in) from viewing site?');
// TRANS: Checkbox label for prohibiting anonymous users from viewing site.
$this->out->checkbox('private', _m('LABEL', 'Private'),
(bool) $this->value('private'),
$instructions);
$this->unli();
$this->li();
// TRANS: Description of the full network notice stream views..
$instructions = _('The full network view includes (public) remote notices which may be unrelated to local conversations.');
// TRANS: Checkbox label for hiding remote network posts if they have not been interacted with locally.
$this->out->checkbox('localonly', _('Restrict full network view to accounts'),
(bool) $this->value('localonly', 'public'),
$instructions);
$this->unli();
$this->out->elementEnd('ul');
$this->out->elementEnd('fieldset');
}
/**
* Action elements
*
* @return void
*/
function formActions()
{
// TRANS: Button title to save access settings in site admin panel.
$title = _('Save access settings.');
// TRANS: Button text to save access settings in site admin panel.
$this->out->submit('submit', _m('BUTTON', 'Save'), 'submit', null, $title);
}
}

View File

@@ -1,161 +0,0 @@
<?php
/**
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2008-2010, StatusNet, Inc.
*
* Action to add a people tag to a user.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* PHP version 5
*
* @category Action
* @package StatusNet
* @author Shashi Gowda <connect2shashi@gmail.com>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
require_once INSTALLDIR . '/lib/togglepeopletag.php';
/**
*
* Action to tag a profile with a single tag.
*
* Takes parameters:
*
* - tagged: the ID of the profile being tagged
* - token: session token to prevent CSRF attacks
* - ajax: boolean; whether to return Ajax or full-browser results
* - peopletag_id: the ID of the tag being used
*
* Only works if the current user is logged in.
*
* @category Action
* @package StatusNet
* @author Shashi Gowda <connect2shashi@gmail.com>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
* @link http://status.net/
*/
class AddpeopletagAction extends Action
{
var $user;
var $tagged;
var $peopletag;
/**
* Check pre-requisites and instantiate attributes
*
* @param Array $args array of arguments (URL, GET, POST)
*
* @return boolean success flag
*/
function prepare(array $args = array())
{
parent::prepare($args);
// CSRF protection
$token = $this->trimmed('token');
if (!$token || $token != common_session_token()) {
// TRANS: Client error displayed when the session token does not match or is not given.
$this->clientError(_('There was a problem with your session token.'.
' Try again, please.'));
}
// Only for logged-in users
$this->user = common_current_user();
if (empty($this->user)) {
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
$this->clientError(_('Not logged in.'));
}
// Profile to subscribe to
$tagged_id = $this->arg('tagged');
$this->tagged = Profile::getKV('id', $tagged_id);
if (empty($this->tagged)) {
// TRANS: Client error displayed trying to perform an action related to a non-existing profile.
$this->clientError(_('No such profile.'));
}
$id = $this->arg('peopletag_id');
$this->peopletag = Profile_list::getKV('id', $id);
if (empty($this->peopletag)) {
// TRANS: Client error displayed trying to reference a non-existing list.
$this->clientError(_('No such list.'));
}
return true;
}
/**
* Handle request
*
* Does the tagging and returns results.
*
* @param Array $args unused.
*
* @return void
*/
function handle()
{
// Throws exception on error
$ptag = Profile_tag::setTag($this->user->id, $this->tagged->id,
$this->peopletag->tag);
if (!$ptag) {
$user = User::getKV('id', $id);
if ($user) {
$this->clientError(
// TRANS: Client error displayed when an unknown error occurs when adding a user to a list.
// TRANS: %s is a username.
sprintf(_('There was an unexpected error while listing %s.'),
$user->nickname));
} else {
// TRANS: Client error displayed when an unknown error occurs when adding a user to a list.
// TRANS: %s is a profile URL.
$this->clientError(sprintf(_('There was a problem listing %s. ' .
'The remote server is probably not responding correctly. ' .
'Please try retrying later.'), $this->profile->profileurl));
}
}
if ($this->boolean('ajax')) {
$this->startHTML('text/xml;charset=utf-8');
$this->elementStart('head');
// TRANS: Title after adding a user to a list.
$this->element('title', null, _m('TITLE','Listed'));
$this->elementEnd('head');
$this->elementStart('body');
$unsubscribe = new UntagButton($this, $this->tagged, $this->peopletag);
$unsubscribe->show();
$this->elementEnd('body');
$this->endHTML();
} else {
$url = common_local_url('subscriptions',
array('nickname' => $this->user->nickname));
common_redirect($url, 303);
}
}
}

View File

@@ -1,182 +0,0 @@
<?php
/**
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2008-2011, StatusNet, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Actions
* @package Actions
* @author Adrian Lang <mail@adrianlang.de>
* @author Brenda Wallace <shiny@cpan.org>
* @author Brion Vibber <brion@pobox.com>
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Meitar Moscovitz <meitarm@gmail.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <millette@status.net>
* @author Sarven Capadisli <csarven@status.net>
* @author Siebrand Mazeland <s.mazeland@xs4all.nl>
* @author Zach Copley <zach@status.net>
* @copyright 2009-2014 Free Software Foundation, Inc http://www.fsf.org
* @license GNU Affero General Public License http://www.gnu.org/licenses/
* @link http://status.net
*/
if (!defined('GNUSOCIAL')) { exit(1); }
class AllAction extends ShowstreamAction
{
public function getStream()
{
if ($this->scoped instanceof Profile && $this->scoped->isLocal() && $this->scoped->getUser()->streamModeOnly()) {
$stream = new InboxNoticeStream($this->target, $this->scoped);
} else {
$stream = new ThreadingInboxNoticeStream($this->target, $this->scoped);
}
return $stream;
}
function title()
{
if (!empty($this->scoped) && $this->scoped->sameAs($this->target)) {
// TRANS: Title of a user's own start page.
return _('Home timeline');
} else {
// TRANS: Title of another user's start page.
// TRANS: %s is the other user's name.
return sprintf(_("%s's home timeline"), $this->target->getBestName());
}
}
function getFeeds()
{
return array(
new Feed(Feed::JSON,
common_local_url(
'ApiTimelineFriends', array(
'format' => 'as',
'id' => $this->target->getNickname()
)
),
// TRANS: %s is user nickname.
sprintf(_('Feed for friends of %s (Activity Streams JSON)'), $this->target->getNickname())),
new Feed(Feed::RSS1,
common_local_url(
'allrss', array(
'nickname' =>
$this->target->getNickname())
),
// TRANS: %s is user nickname.
sprintf(_('Feed for friends of %s (RSS 1.0)'), $this->target->getNickname())),
new Feed(Feed::RSS2,
common_local_url(
'ApiTimelineFriends', array(
'format' => 'rss',
'id' => $this->target->getNickname()
)
),
// TRANS: %s is user nickname.
sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->target->getNickname())),
new Feed(Feed::ATOM,
common_local_url(
'ApiTimelineFriends', array(
'format' => 'atom',
'id' => $this->target->getNickname()
)
),
// TRANS: %s is user nickname.
sprintf(_('Feed for friends of %s (Atom)'), $this->target->getNickname()))
);
}
function showEmptyListMessage()
{
// TRANS: Empty list message. %s is a user nickname.
$message = sprintf(_('This is the timeline for %s and friends but no one has posted anything yet.'), $this->target->getNickname()) . ' ';
if (common_logged_in()) {
if ($this->target->id === $this->scoped->id) {
// TRANS: Encouragement displayed on logged in user's empty timeline.
// TRANS: This message contains Markdown links. Keep "](" together.
$message .= _('Try subscribing to more people, [join a group](%%action.groups%%) or post something yourself.');
} else {
// TRANS: %1$s is user nickname, %2$s is user nickname, %2$s is user nickname prefixed with "@".
// TRANS: This message contains Markdown links. Keep "](" together.
$message .= sprintf(_('You can try to [nudge %1$s](../%2$s) from their profile or [post something to them](%%%%action.newnotice%%%%?status_textarea=%3$s).'), $this->target->getNickname(), $this->target->getNickname(), '@' . $this->target->getNickname());
}
} else {
// TRANS: Encouragement displayed on empty timeline user pages for anonymous users.
// TRANS: %s is a user nickname. This message contains Markdown links. Keep "](" together.
$message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to them.'), $this->target->getNickname());
}
$this->elementStart('div', 'guide');
$this->raw(common_markup_to_html($message));
$this->elementEnd('div');
}
function showContent()
{
if (Event::handle('StartShowAllContent', array($this))) {
if ($this->scoped instanceof Profile && $this->scoped->isLocal() && $this->scoped->getUser()->streamModeOnly()) {
$nl = new PrimaryNoticeList($this->notice, $this, array('show_n'=>NOTICES_PER_PAGE));
} else {
$nl = new ThreadedNoticeList($this->notice, $this, $this->scoped);
}
$cnt = $nl->show();
if (0 == $cnt) {
$this->showEmptyListMessage();
}
$this->pagination(
$this->page > 1, $cnt > NOTICES_PER_PAGE,
$this->page, 'all', array('nickname' => $this->target->getNickname())
);
Event::handle('EndShowAllContent', array($this));
}
}
function showSections()
{
// Show invite button, as long as site isn't closed, and
// we have a logged in user.
if (common_config('invite', 'enabled') && !common_config('site', 'closed') && common_logged_in()) {
if (!common_config('site', 'private')) {
$ibs = new InviteButtonSection(
$this,
// TRANS: Button text for inviting more users to the StatusNet instance.
// TRANS: Less business/enterprise-oriented language for public sites.
_m('BUTTON', 'Send invite')
);
} else {
$ibs = new InviteButtonSection($this);
}
$ibs->show();
}
}
}
class ThreadingInboxNoticeStream extends ThreadingNoticeStream
{
function __construct(Profile $target, Profile $scoped=null)
{
parent::__construct(new InboxNoticeStream($target, $scoped));
}
}

View File

@@ -1,73 +0,0 @@
<?php
/**
* RSS feed for user and friends timeline action class.
*
* PHP version 5
*
* @category Action
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <millette@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/
*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2008, 2009, StatusNet, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* RSS feed for user and friends timeline.
*
* Formatting of RSS handled by Rss10Action
*
* @category Action
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <millette@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/
*/
class AllrssAction extends TargetedRss10Action
{
protected function getNotices()
{
$stream = new InboxNoticeStream($this->target, $this->scoped);
return $stream->getNotices(0, $this->limit)->fetchAll();
}
/**
* Get channel.
*
* @return array associative array on channel information
*/
function getChannel()
{
$c = array('url' => common_local_url('allrss',
array('nickname' =>
$this->target->getNickname())),
// TRANS: Message is used as link title. %s is a user nickname.
'title' => sprintf(_('%s and friends'), $this->target->getNickname()),
'link' => common_local_url('all',
array('nickname' =>
$this->target->getNickname())),
// TRANS: Message is used as link description. %1$s is a username, %2$s is a site name.
'description' => sprintf(_('Updates from %1$s and friends on %2$s!'),
$this->target->getNickname(), common_config('site', 'name')));
return $c;
}
}

View File

@@ -1,121 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Dummy action that emulates Twitter's rate limit status API resource
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Brion Vibber <brion@pobox.com>
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <robin@millette.info>
* @author Siebrand Mazeland <s.mazeland@xs4all.nl>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('GNUSOCIAL')) {
exit(1);
}
/**
* We don't have a rate limit, but some clients check this method.
* It always returns the same thing: 150 hits left.
*
* @category API
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiAccountRateLimitStatusAction extends ApiBareAuthAction
{
/**
* Return true if read only.
*
* MAY override
*
* @param array $args other arguments
*
* @return boolean is read only action?
*/
public function isReadOnly($args)
{
return true;
}
/**
* Handle the request
*
* Return some Twitter-ish data about API limits
*
* @return void
* @throws ClientException
*/
protected function handle()
{
parent::handle();
if (!in_array($this->format, ['xml', 'json'])) {
$this->clientError(
// TRANS: Client error displayed when coming across a non-supported API method.
_('API method not found.'),
404,
$this->format
);
}
$reset = new DateTime();
$reset->modify('+1 hour');
$this->initDocument($this->format);
if ($this->format == 'xml') {
$this->elementStart('hash');
$this->element('remaining-hits', ['type' => 'integer'], "150");
$this->element('hourly-limit', ['type' => 'integer'], "150");
$this->element(
'reset-time',
['type' => 'datetime'],
common_date_iso8601($reset->format('r'))
);
$this->element(
'reset_time_in_seconds',
['type' => 'integer'],
strtotime('+1 hour')
);
$this->elementEnd('hash');
} elseif ($this->format == 'json') {
$out = [
'reset_time_in_seconds' => strtotime('+1 hour'),
'remaining_hits' => 150,
'hourly_limit' => 150,
'reset_time' => common_date_rfc2822(
$reset->format('r')
)
];
print json_encode($out);
}
$this->endDocument($this->format);
}
}

View File

@@ -1,194 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Register account
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package GNUsocial
* @author Hannes Mannerheim <h@nnesmannerhe.im>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
class ApiAccountRegisterAction extends ApiAction
{
/**
* Has there been an error?
*/
var $error = null;
/**
* Have we registered?
*/
var $registered = false;
protected $needPost = true;
protected $code = null; // invite code
protected $invite = null; // invite to-be-stored
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
if ($this->format !== 'json') {
$this->clientError('This method currently only serves JSON.', 415);
}
$this->code = $this->trimmed('code');
return true;
}
/**
* Handle the request
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
protected function handle()
{
parent::handle();
$nickname = $this->trimmed('nickname');
$email = $this->trimmed('email');
$fullname = $this->trimmed('fullname');
$homepage = $this->trimmed('homepage');
$bio = $this->trimmed('bio');
$location = $this->trimmed('location');
// We don't trim these... whitespace is OK in a password!
$password = $this->arg('password');
$confirm = $this->arg('confirm');
if (empty($this->code)) {
common_ensure_session();
if (array_key_exists('invitecode', $_SESSION)) {
$this->code = $_SESSION['invitecode'];
}
}
if (common_config('site', 'inviteonly') && empty($this->code)) {
// TRANS: Client error displayed when trying to register to an invite-only site without an invitation.
$this->clientError(_('Sorry, only invited people can register.'), 401);
}
if (!empty($this->code)) {
$this->invite = Invitation::getKV('code', $this->code);
if (empty($this->invite)) {
// TRANS: Client error displayed when trying to register to an invite-only site without a valid invitation.
$this->clientError(_('Sorry, invalid invitation code.'), 401);
}
// Store this in case we need it
common_ensure_session();
$_SESSION['invitecode'] = $this->code;
}
// Input scrubbing
try {
$nickname = Nickname::normalize($nickname, true);
} catch (NicknameException $e) {
// clientError handles Api exceptions with various formats and stuff
$this->clientError($e->getMessage(), $e->getCode());
}
$email = common_canonical_email($email);
if ($email && !Validate::email($email, common_config('email', 'check_domain'))) {
// TRANS: Form validation error displayed when trying to register without a valid e-mail address.
$this->clientError(_('Not a valid email address.'), 400);
} else if ($this->emailExists($email)) {
// TRANS: Form validation error displayed when trying to register with an already registered e-mail address.
$this->clientError(_('Email address already exists.'), 400);
} else if (!is_null($homepage) && (strlen($homepage) > 0) &&
!common_valid_http_url($homepage)) {
// TRANS: Form validation error displayed when trying to register with an invalid homepage URL.
$this->clientError(_('Homepage is not a valid URL.'), 400);
} else if (Profile::bioTooLong($bio)) {
// TRANS: Form validation error on registration page when providing too long a bio text.
// TRANS: %d is the maximum number of characters for bio; used for plural.
$this->clientError(sprintf(_m('Bio is too long (maximum %d character).',
'Bio is too long (maximum %d characters).',
Profile::maxBio()),
Profile::maxBio()), 400);
} else if (strlen($password) < 6) {
// TRANS: Form validation error displayed when trying to register with too short a password.
$this->clientError(_('Password must be 6 or more characters.'), 400);
} else if ($password != $confirm) {
// TRANS: Form validation error displayed when trying to register with non-matching passwords.
$this->clientError(_('Passwords do not match.'), 400);
} else {
// annoy spammers
sleep(7);
if (Event::handle('APIStartRegistrationTry', array($this))) {
try {
$user = User::register(array('nickname' => $nickname,
'password' => $password,
'email' => $email,
'fullname' => $fullname,
'homepage' => $homepage,
'bio' => $bio,
'location' => $location,
'code' => $this->code));
Event::handle('EndRegistrationTry', array($this));
$this->initDocument('json');
$this->showJsonObjects($this->twitterUserArray($user->getProfile()));
$this->endDocument('json');
} catch (Exception $e) {
$this->clientError($e->getMessage(), 400);
}
}
}
}
/**
* Does the given email address already exist?
*
* Checks a canonical email address against the database.
*
* @param string $email email address to check
*
* @return boolean true if the address already exists
*/
function emailExists($email)
{
$email = common_canonical_email($email);
if (!$email || strlen($email) == 0) {
return false;
}
$user = User::getKV('email', $email);
return is_object($user);
}
}

View File

@@ -1,90 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Update a user's background color
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package GNUsocial
* @author Hannes Mannerheim <h@nnesmannerhe.im>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
class ApiAccountUpdateBackgroundColorAction extends ApiAuthAction
{
var $backgroundcolor = null;
protected $needPost = true;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
if ($this->format !== 'json') {
$this->clientError('This method currently only serves JSON.', 415);
}
$this->backgroundcolor = $this->trimmed('backgroundcolor');
return true;
}
/**
* Handle the request
*
* Try to save the user's colors in her design. Create a new design
* if the user doesn't already have one.
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
protected function handle()
{
parent::handle();
$validhex = preg_match('/^[a-f0-9]{6}$/i',$this->backgroundcolor);
if ($validhex === false || $validhex == 0) {
$this->clientError(_('Not a valid hex color.'), 400);
}
// save the new color
$original = clone($this->auth_user);
$this->auth_user->backgroundcolor = $this->backgroundcolor;
if (!$this->auth_user->update($original)) {
$this->clientError(_('Error updating user.'), 404);
}
$twitter_user = $this->twitterUserArray($this->scoped, true);
$this->initDocument('json');
$this->showJsonObjects($twitter_user);
$this->endDocument('json');
}
}

View File

@@ -1,147 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Update the authenticating user notification channels
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Siebrand Mazeland <s.mazeland@xs4all.nl>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Sets which channel (device) StatusNet delivers updates to for
* the authenticating user. Sending none as the device parameter
* will disable IM and/or SMS updates.
*
* @category API
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiAccountUpdateDeliveryDeviceAction extends ApiAuthAction
{
protected $needPost = true;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
function prepare(array $args = array())
{
parent::prepare($args);
$this->user = $this->auth_user;
$this->device = $this->trimmed('device');
return true;
}
/**
* Handle the request
*
* See which request params have been set, and update the user settings
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
function handle()
{
parent::handle();
if (!in_array($this->format, array('xml', 'json'))) {
$this->clientError(
// TRANS: Client error displayed when coming across a non-supported API method.
_('API method not found.'),
404,
$this->format
);
}
// Note: Twitter no longer supports IM
if (!in_array(strtolower($this->device), array('sms', 'im', 'none'))) {
// TRANS: Client error displayed when no valid device parameter is provided for a user's delivery device setting.
$this->clientError(_( 'You must specify a parameter named ' .
'\'device\' with a value of one of: sms, im, none.' ));
}
if (empty($this->user)) {
// TRANS: Client error displayed when no existing user is provided for a user's delivery device setting.
$this->clientError(_('No such user.'), 404);
}
$original = clone($this->user);
if (strtolower($this->device) == 'sms') {
$this->user->smsnotify = true;
} elseif (strtolower($this->device) == 'im') {
//TODO IM is pluginized now, so what should we do?
//Enable notifications for all IM plugins?
//For now, don't do anything
//$this->user->jabbernotify = true;
} elseif (strtolower($this->device == 'none')) {
$this->user->smsnotify = false;
//TODO IM is pluginized now, so what should we do?
//Disable notifications for all IM plugins?
//For now, don't do anything
//$this->user->jabbernotify = false;
}
$result = $this->user->update($original);
if ($result === false) {
common_log_db_error($this->user, 'UPDATE', __FILE__);
// TRANS: Server error displayed when a user's delivery device cannot be updated.
$this->serverError(_('Could not update user.'));
}
$profile = $this->user->getProfile();
$twitter_user = $this->twitterUserArray($profile, true);
// Note: this Twitter API method is retarded because it doesn't give
// any success/failure information. Twitter's docs claim that the
// notification field will change to reflect notification choice,
// but that's not true; notification> is used to indicate
// whether the auth user is following the user in question.
if ($this->format == 'xml') {
$this->initDocument('xml');
$this->showTwitterXmlUser($twitter_user, 'user', true);
$this->endDocument('xml');
} elseif ($this->format == 'json') {
$this->initDocument('json');
$this->showJsonObjects($twitter_user);
$this->endDocument('json');
}
}
}

View File

@@ -1,89 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Update a user's link color
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package GNUsocial
* @author Hannes Mannerheim <h@nnesmannerhe.im>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
class ApiAccountUpdateLinkColorAction extends ApiAuthAction
{
var $linkcolor = null;
protected $needPost = true;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
if ($this->format !== 'json') {
$this->clientError('This method currently only serves JSON.', 415);
}
$this->linkcolor = $this->trimmed('linkcolor');
return true;
}
/**
* Handle the request
*
* Try to save the user's colors in her design. Create a new design
* if the user doesn't already have one.
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
protected function handle()
{
parent::handle();
$validhex = preg_match('/^[a-f0-9]{6}$/i',$this->linkcolor);
if ($validhex === false || $validhex == 0) {
$this->clientError(_('Not a valid hex color.'), 400);
}
// save the new color
$original = clone($this->auth_user);
$this->auth_user->linkcolor = $this->linkcolor;
if (!$this->auth_user->update($original)) {
$this->clientError(_('Error updating user.'), 400);
}
$twitter_user = $this->twitterUserArray($this->scoped, true);
$this->initDocument('json');
$this->showJsonObjects($twitter_user);
$this->endDocument('json');
}
}

View File

@@ -1,141 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Update the authenticating user's profile
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* API analog to the profile settings page
* Only the parameters specified will be updated.
*
* @category API
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiAccountUpdateProfileAction extends ApiAuthAction
{
protected $needPost = true;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->user = $this->auth_user;
$this->name = $this->trimmed('name');
$this->url = $this->trimmed('url');
$this->location = $this->trimmed('location');
$this->description = $this->trimmed('description');
return true;
}
/**
* Handle the request
*
* See which request params have been set, and update the profile
*
* @return void
*/
protected function handle()
{
parent::handle();
if (!in_array($this->format, array('xml', 'json'))) {
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
if (empty($this->user)) {
// TRANS: Client error displayed if a user could not be found.
$this->clientError(_('No such user.'), 404);
}
$profile = $this->user->getProfile();
if (empty($profile)) {
// TRANS: Error message displayed when referring to a user without a profile.
$this->clientError(_('User has no profile.'));
}
$original = clone($profile);
$profile->fullname = $this->name;
$profile->homepage = $this->url;
$profile->bio = $this->description;
$profile->location = $this->location;
if (!empty($this->location)) {
$loc = Location::fromName($this->location);
if (!empty($loc)) {
$profile->lat = $loc->lat;
$profile->lon = $loc->lon;
$profile->location_id = $loc->location_id;
$profile->location_ns = $loc->location_ns;
}
} else {
// location is empty so reset the extrapolated information too
$profile->lat = '';
$profile->lon = '';
$profile->location_id = '';
$profile->location_ns = '';
}
$result = $profile->update($original);
if (!$result) {
common_log_db_error($profile, 'UPDATE', __FILE__);
// TRANS: Server error displayed if a user profile could not be saved.
$this->serverError(_('Could not save profile.'));
}
$twitter_user = $this->twitterUserArray($profile, true);
if ($this->format == 'xml') {
$this->initDocument('xml');
$this->showTwitterXmlUser($twitter_user, 'user', true);
$this->endDocument('xml');
} elseif ($this->format == 'json') {
$this->initDocument('json');
$this->showJsonObjects($twitter_user);
$this->endDocument('json');
}
}
}

View File

@@ -1,112 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Update the authenticating user's profile image
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Updates the authenticating user's profile image. Note that this API method
* expects raw multipart data, not a URL to an image.
*
* @category API
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiAccountUpdateProfileImageAction extends ApiAuthAction
{
protected $needPost = true;
/**
* Handle the request
*
* Check whether the credentials are valid and output the result
*
* @return void
*/
protected function handle()
{
parent::handle();
// Workaround for PHP returning empty $_POST and $_FILES when POST
// length > post_max_size in php.ini
if (empty($_FILES)
&& empty($_POST)
&& ($_SERVER['CONTENT_LENGTH'] > 0)
) {
// TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit.
// TRANS: %s is the number of bytes of the CONTENT_LENGTH.
$msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.',
'The server was unable to handle that much POST data (%s bytes) due to its current configuration.',
intval($_SERVER['CONTENT_LENGTH']));
$this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
}
if (empty($this->user)) {
// TRANS: Client error displayed updating profile image without having a user object.
$this->clientError(_('No such user.'), 404);
}
try {
$imagefile = ImageFile::fromUpload('image');
} catch (Exception $e) {
$this->clientError($e->getMessage());
}
$type = $imagefile->preferredType();
$filename = Avatar::filename(
$user->id,
image_type_to_extension($type),
null,
'tmp'.common_timestamp()
);
$filepath = Avatar::path($filename);
$imagefile->copyTo($filepath);
$profile = $this->user->getProfile();
$profile->setOriginal($filename);
$twitter_user = $this->twitterUserArray($profile, true);
if ($this->format == 'xml') {
$this->initDocument('xml');
$this->showTwitterXmlUser($twitter_user, 'user', true);
$this->endDocument('xml');
} elseif ($this->format == 'json') {
$this->initDocument('json');
$this->showJsonObjects($twitter_user);
$this->endDocument('json');
}
}
}

View File

@@ -1,85 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Test if supplied user credentials are valid.
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Check a user's credentials. Returns an HTTP 200 OK response code and a
* representation of the requesting user if authentication was successful;
* returns a 401 status code and an error message if not.
*
* @category API
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiAccountVerifyCredentialsAction extends ApiAuthAction
{
protected function handle()
{
parent::handle();
if (!in_array($this->format, array('xml', 'json'))) {
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), $code = 404);
}
$twitter_user = $this->twitterUserArray($this->auth_user->getProfile(), true);
if ($this->format == 'xml') {
$this->initDocument('xml');
$this->showTwitterXmlUser($twitter_user, 'user', true);
$this->endDocument('xml');
} elseif ($this->format == 'json') {
$this->initDocument('json');
$this->showJsonObjects($twitter_user);
$this->endDocument('json');
}
}
/**
* Is this action read only?
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
}

View File

@@ -1,136 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* An AtomPub service document for a user
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Shows an AtomPub service document for a user
*
* @category API
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
* @link http://status.net/
*/
class ApiAtomServiceAction extends ApiBareAuthAction
{
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*
*/
function prepare(array $args = array())
{
parent::prepare($args);
$this->user = $this->getTargetUser($this->arg('id'));
if (empty($this->user)) {
// TRANS: Client error displayed when making an Atom API request for an unknown user.
$this->clientError(_('No such user.'), 404);
}
return true;
}
/**
* Handle the arguments. In our case, show a service document.
*
* @param Array $args unused.
*
* @return void
*/
function handle()
{
parent::handle();
header('Content-Type: application/atomsvc+xml');
$this->startXML();
$this->elementStart('service', array('xmlns' => 'http://www.w3.org/2007/app',
'xmlns:atom' => 'http://www.w3.org/2005/Atom',
'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/'));
$this->elementStart('workspace');
// TRANS: Title for Atom feed.
$this->element('atom:title', null, _m('ATOM','Main'));
$this->elementStart('collection',
array('href' => common_local_url('ApiTimelineUser',
array('id' => $this->user->id,
'format' => 'atom'))));
$this->element('atom:title',
null,
// TRANS: Title for Atom feed. %s is a user nickname.
sprintf(_("%s timeline"),
$this->user->nickname));
$this->element('accept', null, 'application/atom+xml;type=entry');
$this->element('activity:verb', null, ActivityVerb::POST);
$this->elementEnd('collection');
$this->elementStart('collection',
array('href' => common_local_url('AtomPubSubscriptionFeed',
array('subscriber' => $this->user->id))));
$this->element('atom:title',
null,
// TRANS: Title for Atom feed with a user's subscriptions. %s is a user nickname.
sprintf(_("%s subscriptions"),
$this->user->nickname));
$this->element('accept', null, 'application/atom+xml;type=entry');
$this->element('activity:verb', null, ActivityVerb::FOLLOW);
$this->elementEnd('collection');
$this->elementStart('collection',
array('href' => common_local_url('AtomPubFavoriteFeed',
array('profile' => $this->user->id))));
$this->element('atom:title',
null,
// TRANS: Title for Atom feed with a user's favorite notices. %s is a user nickname.
sprintf(_("%s favorites"),
$this->user->nickname));
$this->element('accept', null, 'application/atom+xml;type=entry');
$this->element('activity:verb', null, ActivityVerb::FAVORITE);
$this->elementEnd('collection');
$this->elementStart('collection',
array('href' => common_local_url('AtomPubMembershipFeed',
array('profile' => $this->user->id))));
$this->element('atom:title',
null,
// TRANS: Title for Atom feed with a user's memberships. %s is a user nickname.
sprintf(_("%s memberships"),
$this->user->nickname));
$this->element('accept', null, 'application/atom+xml;type=entry');
$this->element('activity:verb', null, ActivityVerb::JOIN);
$this->elementEnd('collection');
$this->elementEnd('workspace');
$this->elementEnd('service');
$this->endXML();
}
}

View File

@@ -1,106 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show a notice's attachment
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package GNUsocial
* @author Hannes Mannerheim <h@nnesmannerhe.im>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Show a notice's attachment
*
*/
class ApiAttachmentAction extends ApiAuthAction
{
const MAXCOUNT = 100;
var $original = null;
var $cnt = self::MAXCOUNT;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
if ($this->format !== 'json') {
$this->clientError('This method currently only serves JSON.', 415);
}
return true;
}
/**
* Handle the request
*
* Make a new notice for the update, save it, and show it
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
protected function handle()
{
parent::handle();
$file = new File();
$file->selectAdd(); // clears it
$file->selectAdd('url');
$file->id = $this->trimmed('id');
$url = $file->fetchAll('url');
$file_txt = '';
if(strstr($url[0],'.html')) {
$file_txt['txt'] = file_get_contents($url[0]);
$file_txt['body_start'] = strpos($file_txt['txt'],'<body>')+6;
$file_txt['body_end'] = strpos($file_txt['txt'],'</body>');
$file_txt = substr($file_txt['txt'],$file_txt['body_start'],$file_txt['body_end']-$file_txt['body_start']);
}
$this->initDocument('json');
$this->showJsonObjects($file_txt);
$this->endDocument('json');
}
/**
* Return true if read only.
*
* MAY override
*
* @param array $args other arguments
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
return true;
}
}

View File

@@ -1,113 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Block a user via the API
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009-2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Blocks the user specified in the ID parameter as the authenticating user.
* Destroys a friendship to the blocked user if it exists. Returns the
* blocked user in the requested format when successful.
*
* @category API
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiBlockCreateAction extends ApiAuthAction
{
protected $needPost = true;
var $other = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->other = $this->getTargetProfile($this->arg('id'));
return true;
}
/**
* Handle the request
*
* Save the new message
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
protected function handle()
{
parent::handle();
if (empty($this->user) || empty($this->other)) {
// TRANS: Client error displayed when trying to block a non-existing user or a user from another site.
$this->clientError(_('No such user.'), 404);
}
// Don't allow blocking yourself!
if ($this->user->id == $this->other->id) {
// TRANS: Client error displayed when users try to block themselves.
$this->clientError(_("You cannot block yourself!"), 403);
}
if (!$this->user->hasBlocked($this->other)) {
if (Event::handle('StartBlockProfile', array($this->user, $this->other))) {
$result = $this->user->block($this->other);
if ($result) {
Event::handle('EndBlockProfile', array($this->user, $this->other));
}
}
}
if ($this->user->hasBlocked($this->other)) {
$this->initDocument($this->format);
$this->showProfile($this->other, $this->format);
$this->endDocument($this->format);
} else {
// TRANS: Server error displayed when blocking a user has failed.
$this->serverError(_('Block user failed.'), 500);
}
}
}

View File

@@ -1,102 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Un-block a user via the API
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009-2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Un-blocks the user specified in the ID parameter for the authenticating user.
* Returns the un-blocked user in the requested format when successful.
*
* @category API
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiBlockDestroyAction extends ApiAuthAction
{
protected $needPost = true;
var $other = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->other = $this->getTargetProfile($this->arg('id'));
return true;
}
/**
* Handle the request
*
* Save the new message
*
* @return void
*/
protected function handle()
{
parent::handle();
if (empty($this->user) || empty($this->other)) {
// TRANS: Client error when user not found for an API action to remove a block for a user.
$this->clientError(_('No such user.'), 404);
}
if ($this->user->hasBlocked($this->other)) {
if (Event::handle('StartUnblockProfile', array($this->user, $this->other))) {
$result = $this->user->unblock($this->other);
if ($result) {
Event::handle('EndUnblockProfile', array($this->user, $this->other));
}
}
}
if (!$this->user->hasBlocked($this->other)) {
$this->initDocument($this->format);
$this->showProfile($this->other, $this->format);
$this->endDocument($this->format);
} else {
// TRANS: Server error displayed when unblocking a user has failed.
$this->serverError(_('Unblock user failed.'));
}
}
}

View File

@@ -1,115 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show a notice's attachment
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package GNUsocial
* @author Hannes Mannerheim <h@nnesmannerhe.im>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Check if a url have a push-hub, i.e. if it is possible to subscribe
*
*/
class ApiCheckHubAction extends ApiAuthAction
{
protected $url = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
if ($this->format !== 'json') {
$this->clientError('This method currently only serves JSON.', 415);
}
$this->url = urldecode($args['url']);
if (empty($this->url)) {
$this->clientError(_('No URL.'), 403);
}
if (!common_valid_http_url($this->url)) {
$this->clientError(_('Invalid URL.'), 403);
}
return true;
}
/**
* Handle the request
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
protected function handle()
{
parent::handle();
$discover = new FeedDiscovery();
try {
$feeduri = $discover->discoverFromURL($this->url);
if($feeduri) {
$huburi = $discover->getHubLink();
}
} catch (FeedSubNoFeedException $e) {
$this->clientError(_('No feed found'), 403);
} catch (FeedSubBadResponseException $e) {
$this->clientError(_('No hub found'), 403);
}
$hub_status = array();
if ($huburi) {
$hub_status = array('huburi' => $huburi);
}
$this->initDocument('json');
$this->showJsonObjects($hub_status);
$this->endDocument('json');
}
/**
* Return true if read only.
*
* MAY override
*
* @param array $args other arguments
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
return true;
}
}

View File

@@ -1,69 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Check nickname
*
* Returns 1 if nickname is available on this instance, 0 if not. Error if site is private.
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package GNUsocial
* @author Hannes Mannerheim <h@nnesmannerhe.im>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
class ApiCheckNicknameAction extends ApiAction
{
protected function prepare(array $args=array())
{
parent::prepare($args);
if (common_config('site', 'private')) {
$this->clientError(_('This site is private.'), 403);
}
if ($this->format !== 'json') {
$this->clientError('This method currently only serves JSON.', 415);
}
return true;
}
protected function handle()
{
parent::handle();
$nickname = $this->trimmed('nickname');
try {
Nickname::normalize($nickname, true);
$nickname_ok = 1;
} catch (NicknameException $e) {
$nickname_ok = 0;
}
$this->initDocument('json');
$this->showJsonObjects($nickname_ok);
$this->endDocument('json');
}
}

View File

@@ -1,227 +0,0 @@
<?php
/**
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2011, StatusNet, Inc.
*
* Show a stream of notices in a particular conversation
*
* PHP version 5
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2011 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
// This check helps protect against security problems;
// your code file can't be executed directly from the web.
exit(1);
}
/**
* Show a stream of notices in a particular conversation
*
* @category API
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2011 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class ApiconversationAction extends ApiAuthAction
{
protected $conversation = null;
protected $notices = null;
protected function prepare(array $args=array())
{
parent::prepare($args);
$convId = $this->trimmed('id');
if (empty($convId)) {
// TRANS: Client exception thrown when no conversation ID is given.
throw new ClientException(_('No conversation ID.'));
}
$this->conversation = Conversation::getKV('id', $convId);
if (empty($this->conversation)) {
// TRANS: Client exception thrown when referring to a non-existing conversation ID (%d).
throw new ClientException(sprintf(_('No conversation with ID %d.'), $convId),
404);
}
$stream = new ConversationNoticeStream($convId, $this->scoped);
$notice = $stream->getNotices(($this->page-1) * $this->count,
$this->count,
$this->since_id,
$this->max_id);
$this->notices = $notice->fetchAll();
return true;
}
/**
* Handler method
*
* @param array $argarray is ignored since it's now passed in in prepare()
*
* @return void
*/
function handle($argarray=null)
{
$sitename = common_config('site', 'name');
// TRANS: Title for conversion timeline.
$title = _m('TITLE', 'Conversation');
$id = common_local_url('apiconversation', array('id' => $this->conversation->id, 'format' => $this->format));
$link = common_local_url('conversation', array('id' => $this->conversation->id));
$self = $id;
switch($this->format) {
case 'xml':
$this->showXmlTimeline($this->notices);
break;
case 'rss':
$this->showRssTimeline(
$this->notices,
$title,
$link,
null,
null,
null,
$self
);
break;
case 'atom':
header('Content-Type: application/atom+xml; charset=utf-8');
$atom = new AtomNoticeFeed($this->auth_user);
$atom->setId($id);
$atom->setTitle($title);
$atom->setUpdated('now');
$atom->addLink($link);
$atom->setSelfLink($self);
$atom->addEntryFromNotices($this->notices);
$this->raw($atom->getString());
break;
case 'json':
$this->showJsonTimeline($this->notices);
break;
case 'as':
header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE);
$doc = new ActivityStreamJSONDocument($this->auth_user);
$doc->setTitle($title);
$doc->addLink($link, 'alternate', 'text/html');
$doc->addItemsFromNotices($this->notices);
$this->raw($doc->asString());
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), $code = 404);
break;
}
}
/**
* Return true if read only.
*
* MAY override
*
* @param array $args other arguments
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
return true;
} else {
return false;
}
}
/**
* Return last modified, if applicable.
*
* MAY override
*
* @return string last modified http header
*/
function lastModified()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
return strtotime($this->notices[0]->created);
}
return null;
}
/**
* Return etag, if applicable.
*
* MAY override
*
* @return string etag http header
*/
function etag()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
$last = count($this->notices) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
$this->user->id,
strtotime($this->notices[0]->created),
strtotime($this->notices[$last]->created))
)
. '"';
}
return null;
}
/**
* Does this require authentication?
*
* @return boolean true if delete, else false
*/
function requiresAuth()
{
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
$_SERVER['REQUEST_METHOD'] == 'HEAD') {
return false;
} else {
return true;
}
}
}

View File

@@ -1,99 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show an external user's profile information
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package GNUsocial
* @author Hannes Mannerheim <h@nnesmannerhe.im>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Ouputs information for a user, specified by ID or screen name.
* The user's most recent status will be returned inline.
*/
class ApiExternalProfileShowAction extends ApiPrivateAuthAction
{
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
if ($this->format !== 'json') {
$this->clientError('This method currently only serves JSON.', 415);
}
$profileurl = urldecode($this->arg('profileurl'));
// TODO: Make this more ... unique!
$this->profile = Profile::getKV('profileurl', $profileurl);
if (!($this->profile instanceof Profile)) {
// TRANS: Client error displayed when requesting profile information for a non-existing profile.
$this->clientError(_('Profile not found.'), 404);
}
return true;
}
/**
* Handle the request
*
* Check the format and show the user info
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
protected function handle()
{
parent::handle();
$twitter_user = $this->twitterUserArray($this->profile, true);
$this->initDocument('json');
$this->showJsonObjects($twitter_user);
$this->endDocument('json');
}
/**
* Return true if read only.
*
* MAY override
*
* @param array $args other arguments
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
return true;
}
}

View File

@@ -1,111 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Subscribe to a user via the API
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009-2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Allows the authenticating users to follow (subscribe) the user specified in
* the ID parameter. Returns the befriended user in the requested format when
* successful. Returns a string describing the failure condition when unsuccessful.
*
* @category API
* @package StatusNet
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiFriendshipsCreateAction extends ApiAuthAction
{
protected $needPost = true;
var $other = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->other = $this->getTargetProfile($this->arg('id'));
return true;
}
/**
* Handle the request
*
* Check the format and show the user info
*
* @return void
*/
protected function handle()
{
parent::handle();
if (!in_array($this->format, array('xml', 'json'))) {
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
if (empty($this->other)) {
// TRANS: Client error displayed when trying follow who's profile could not be found.
$this->clientError(_('Could not follow user: profile not found.'), 403);
}
if ($this->scoped->isSubscribed($this->other)) {
$errmsg = sprintf(
// TRANS: Client error displayed when trying to follow a user that's already being followed.
// TRANS: %s is the nickname of the user that is already being followed.
_('Could not follow user: %s is already on your list.'),
$this->other->nickname
);
$this->clientError($errmsg, 403);
}
try {
Subscription::start($this->scoped, $this->other);
} catch (AlreadyFulfilledException $e) {
$this->clientError($e->getMessage(), 409);
}
$this->initDocument($this->format);
$this->showProfile($this->other, $this->format);
$this->endDocument($this->format);
}
}

View File

@@ -1,114 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Unsubscribe to a user via API
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009-2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Allows the authenticating users to unfollow (unsubscribe) the user specified in
* the ID parameter. Returns the unfollowed user in the requested format when
* successful. Returns a string describing the failure condition when unsuccessful.
*
* @category API
* @package StatusNet
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiFriendshipsDestroyAction extends ApiAuthAction
{
protected $needPost = true;
protected $other = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->other = $this->getTargetProfile($this->arg('id'));
return true;
}
/**
* Handle the request
*
* Check the format and show the user info
*
* @return void
*/
protected function handle()
{
parent::handle();
if (!in_array($this->format, array('xml', 'json'))) {
$this->clientError(
// TRANS: Client error displayed when coming across a non-supported API method.
_('API method not found.'),
404
);
}
if (!$this->other instanceof Profile) {
$this->clientError(
// TRANS: Client error displayed when trying to unfollow a user that cannot be found.
_('Could not unfollow user: User not found.'),
403
);
}
// Don't allow unsubscribing from yourself!
if ($this->scoped->id == $this->other->id) {
$this->clientError(
// TRANS: Client error displayed when trying to unfollow self.
_("You cannot unfollow yourself."),
403
);
}
// throws an exception on error
Subscription::cancel($this->scoped, $this->other);
$this->initDocument($this->format);
$this->showProfile($this->other, $this->format);
$this->endDocument($this->format);
}
}

View File

@@ -1,118 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show whether there is a friendship between two users
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009-2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Tests for the existence of friendship between two users. Will return true if
* user_a follows user_b, otherwise will return false.
*
* @category API
* @package StatusNet
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiFriendshipsExistsAction extends ApiPrivateAuthAction
{
var $profile_a = null;
var $profile_b = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->profile_a = $this->getTargetProfile($this->trimmed('user_a'));
$this->profile_b = $this->getTargetProfile($this->trimmed('user_b'));
return true;
}
/**
* Handle the request
*
* Check the format and show the user info
*
* @return void
*/
protected function handle()
{
parent::handle();
if (empty($this->profile_a) || empty($this->profile_b)) {
$this->clientError(
// TRANS: Client error displayed when supplying invalid parameters to an API call checking if a friendship exists.
_('Two valid IDs or nick names must be supplied.'),
400
);
}
$result = Subscription::exists($this->profile_a, $this->profile_b);
switch ($this->format) {
case 'xml':
$this->initDocument('xml');
$this->element('friends', null, $result);
$this->endDocument('xml');
break;
case 'json':
$this->initDocument('json');
print json_encode($result);
$this->endDocument('json');
break;
default:
break;
}
}
/**
* Return true if read only.
*
* MAY override
*
* @param array $args other arguments
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
return true;
}
}

View File

@@ -1,169 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show information about the relationship between two users
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Outputs detailed information about the relationship between two users
*
* @category API
* @package StatusNet
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiFriendshipsShowAction extends ApiBareAuthAction
{
var $source = null;
var $target = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$source_id = (int)$this->trimmed('source_id');
$source_screen_name = $this->trimmed('source_screen_name');
$target_id = (int)$this->trimmed('target_id');
$target_screen_name = $this->trimmed('target_screen_name');
if (!empty($source_id)) {
$this->source = User::getKV($source_id);
} elseif (!empty($source_screen_name)) {
$this->source = User::getKV('nickname', $source_screen_name);
} else {
$this->source = $this->auth_user;
}
if (!empty($target_id)) {
$this->target = User::getKV($target_id);
} elseif (!empty($target_screen_name)) {
$this->target = User::getKV('nickname', $target_screen_name);
}
return true;
}
/**
* Determines whether this API resource requires auth. Overloaded to look
* return true in case source_id and source_screen_name are both empty
*
* @return boolean true or false
*/
function requiresAuth()
{
if (common_config('site', 'private')) {
return true;
}
$source_id = $this->trimmed('source_id');
$source_screen_name = $this->trimmed('source_screen_name');
if (empty($source_id) && empty($source_screen_name)) {
return true;
}
return false;
}
/**
* Handle the request
*
* Check the format and show the user info
*
* @return void
*/
protected function handle()
{
parent::handle();
if (!in_array($this->format, array('xml', 'json'))) {
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
if (empty($this->source)) {
$this->clientError(
// TRANS: Client error displayed when a source user could not be determined showing friendship.
_('Could not determine source user.'),
404
);
}
if (empty($this->target)) {
$this->clientError(
// TRANS: Client error displayed when a target user could not be determined showing friendship.
_('Could not find target user.'),
404
);
}
$result = $this->twitterRelationshipArray($this->source, $this->target);
switch ($this->format) {
case 'xml':
$this->initDocument('xml');
$this->showTwitterXmlRelationship($result[relationship]);
$this->endDocument('xml');
break;
case 'json':
$this->initDocument('json');
print json_encode($result);
$this->endDocument('json');
break;
default:
break;
}
}
/**
* Return true if read only.
*
* MAY override
*
* @param array $args other arguments
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
return true;
}
}

View File

@@ -1,148 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Dump of configuration variables
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package GNUsocial
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Gives a full dump of configuration variables for this instance
* of GNU social, minus variables that may be security-sensitive (like
* passwords).
* URL: https://example.com/api/gnusocial/config.(xml|json)
* Formats: xml, json
*
* @category API
* @package GNUsocial
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
class ApiGNUsocialConfigAction extends ApiAction
{
var $keys = array(
'site' => array('name', 'server', 'theme', 'path', 'logo', 'fancy', 'language',
'email', 'broughtby', 'broughtbyurl', 'timezone', 'closed',
'inviteonly', 'private', 'textlimit', 'ssl', 'sslserver'),
'license' => array('type', 'owner', 'url', 'title', 'image'),
'nickname' => array('featured'),
'profile' => array('biolimit'),
'group' => array('desclimit'),
'notice' => array('contentlimit'),
'throttle' => array('enabled', 'count', 'timespan'),
'xmpp' => array('enabled', 'server', 'port', 'user'),
'integration' => array('source'),
'attachments' => array('uploads', 'file_quota'),
'url' => array('maxurllength', 'maxnoticelength'),
);
protected function handle()
{
parent::handle();
switch ($this->format) {
case 'xml':
$this->initDocument('xml');
$this->elementStart('config');
// XXX: check that all sections and settings are legal XML elements
foreach ($this->keys as $section => $settings) {
$this->elementStart($section);
foreach ($settings as $setting) {
$value = $this->setting($section, $setting);
if (is_array($value)) {
$value = implode(',', $value);
} else if ($value === false || $value == '0') {
$value = 'false';
} else if ($value === true || $value == '1') {
$value = 'true';
}
// return theme logo if there's no site specific one
if (empty($value)) {
if ($section == 'site' && $setting == 'logo') {
$value = Theme::path('logo.png');
}
}
$this->element($setting, null, $value);
}
$this->elementEnd($section);
}
$this->elementEnd('config');
$this->endDocument('xml');
break;
case 'json':
$result = array();
foreach ($this->keys as $section => $settings) {
$result[$section] = array();
foreach ($settings as $setting) {
$result[$section][$setting]
= $this->setting($section, $setting);
}
}
$this->initDocument('json');
$this->showJsonObjects($result);
$this->endDocument('json');
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
function setting($section, $key) {
$result = common_config($section, $key);
if ($key == 'file_quota') {
// hack: adjust for the live upload limit
if (common_config($section, 'uploads')) {
$max = ImageFile::maxFileSizeInt();
} else {
$max = 0;
}
return min($result, $max);
}
return $result;
}
/**
* Return true if read only.
*
* MAY override
*
* @param array $args other arguments
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
return true;
}
}

View File

@@ -1,82 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* A version stamp for the API
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package GNUsocial
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Returns a version number for this version of GNU social, which
* should make things a bit easier for upgrades.
* URL: http://identi.ca/api/statusnet/version.(xml|json)
* Formats: xml, js
*
* @category API
* @package GNUsocial
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
class ApiGNUsocialVersionAction extends ApiPrivateAuthAction
{
protected function handle()
{
parent::handle();
switch ($this->format) {
case 'xml':
$this->initDocument('xml');
$this->element('version', null, GNUSOCIAL_VERSION);
$this->endDocument('xml');
break;
case 'json':
$this->initDocument('json');
print '"'.GNUSOCIAL_VERSION.'"';
$this->endDocument('json');
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
/**
* Return true if read only.
*
* MAY override
*
* @param array $args other arguments
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
return true;
}
}

View File

@@ -1,190 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* List a group's admins
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package GNUsocial
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @author Hannes Mannerheim <h@nnesmannerhe.im>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
if (!defined('GNUSOCIAL')) {
exit(1);
}
/**
* List 20 newest admins of the group specified by name or ID.
*
* @category API
* @package GNUsocial
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @author Hannes Mannerheim <h@nnesmannerhe.im>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
class ApiGroupAdminsAction extends ApiPrivateAuthAction
{
var $group = null;
var $profiles = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->group = $this->getTargetGroup($this->arg('id'));
if (empty($this->group)) {
// TRANS: Client error displayed trying to show group membership on a non-existing group.
$this->clientError(_('Group not found.'), 404);
}
$this->profiles = $this->getProfiles();
return true;
}
/**
* Handle the request
*
* Show the admin of the group
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
protected function handle()
{
parent::handle();
// XXX: RSS and Atom
switch($this->format) {
case 'xml':
$this->showTwitterXmlUsers($this->profiles);
break;
case 'json':
$this->showJsonUsers($this->profiles);
break;
default:
$this->clientError(
// TRANS: Client error displayed when coming across a non-supported API method.
_('API method not found.'),
404,
$this->format
);
break;
}
}
/**
* Fetch the admins of a group
*
* @return array $profiles list of profiles
*/
function getProfiles()
{
$profiles = array();
$profile = $this->group->getAdmins(
($this->page - 1) * $this->count,
$this->count,
$this->since_id,
$this->max_id
);
while ($profile->fetch()) {
$profiles[] = clone($profile);
}
return $profiles;
}
/**
* Is this action read only?
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* When was this list of profiles last modified?
*
* @return string datestamp of the lastest profile in the group
*/
function lastModified()
{
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
return strtotime($this->profiles[0]->created);
}
return null;
}
/**
* An entity tag for this list of groups
*
* Returns an Etag based on the action name, language
* the group id, and timestamps of the first and last
* user who has joined the group
*
* @return string etag
*/
function etag()
{
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
$last = count($this->profiles) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
$this->group->id,
strtotime($this->profiles[0]->created),
strtotime($this->profiles[$last]->created))
)
. '"';
}
return null;
}
}

View File

@@ -1,181 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Create a group via the API
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Make a new group. Sets the authenticated user as the administrator of the group.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiGroupCreateAction extends ApiAuthAction
{
protected $needPost = true;
var $group = null;
var $nickname = null;
var $fullname = null;
var $homepage = null;
var $description = null;
var $location = null;
var $aliasstring = null;
var $aliases = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->nickname = Nickname::normalize($this->arg('nickname'), true);
$this->fullname = $this->arg('full_name');
$this->homepage = $this->arg('homepage');
$this->description = $this->arg('description');
$this->location = $this->arg('location');
$this->aliasstring = $this->arg('aliases');
return true;
}
/**
* Handle the request
*
* Save the new group
*
* @return void
*/
protected function handle()
{
parent::handle();
if (empty($this->user)) {
// TRANS: Client error given when a user was not found (404).
$this->clientError(_('No such user.'), 404);
}
if ($this->validateParams() == false) {
return;
}
$group = User_group::register(array('nickname' => $this->nickname,
'fullname' => $this->fullname,
'homepage' => $this->homepage,
'description' => $this->description,
'location' => $this->location,
'aliases' => $this->aliases,
'userid' => $this->user->id,
'local' => true));
switch($this->format) {
case 'xml':
$this->showSingleXmlGroup($group);
break;
case 'json':
$this->showSingleJsonGroup($group);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
/**
* Validate params for the new group
*
* @return void
*/
function validateParams()
{
if (!is_null($this->homepage)
&& strlen($this->homepage) > 0
&& !common_valid_http_url($this->homepage)) {
// TRANS: Client error in form for group creation.
$this->clientError(_('Homepage is not a valid URL.'), 403);
} elseif (!is_null($this->fullname)
&& mb_strlen($this->fullname) > 255) {
// TRANS: Client error in form for group creation.
$this->clientError(_('Full name is too long (maximum 255 characters).'), 403);
} elseif (User_group::descriptionTooLong($this->description)) {
// TRANS: Client error shown when providing too long a description during group creation.
// TRANS: %d is the maximum number of allowed characters.
$this->clientError(sprintf(_m('Description is too long (maximum %d character).',
'Description is too long (maximum %d characters).',
User_group::maxDescription()), User_group::maxDescription()), 403);
} elseif (!is_null($this->location)
&& mb_strlen($this->location) > 255) {
// TRANS: Client error shown when providing too long a location during group creation.
$this->clientError(_('Location is too long (maximum 255 characters).'), 403);
}
if (!empty($this->aliasstring)) {
$this->aliases = array_map(
array('Nickname', 'normalize'), // static call to Nickname::normalize
array_unique(preg_split('/[\s,]+/', $this->aliasstring))
);
} else {
$this->aliases = array();
}
if (count($this->aliases) > common_config('group', 'maxaliases')) {
$this->clientError(sprintf(
// TRANS: Client error shown when providing too many aliases during group creation.
// TRANS: %d is the maximum number of allowed aliases.
_m('Too many aliases! Maximum %d allowed.',
'Too many aliases! Maximum %d allowed.',
common_config('group', 'maxaliases')),
common_config('group', 'maxaliases')),
403);
}
// Everything looks OK
return true;
}
}

View File

@@ -1,125 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Check to see whether a user a member of a group
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Returns whether a user is a member of a specified group.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiGroupIsMemberAction extends ApiBareAuthAction
{
var $group = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->target = $this->getTargetProfile(null);
$this->group = $this->getTargetGroup(null);
return true;
}
/**
* Handle the request
*
* Save the new message
*
* @return void
*/
protected function handle()
{
parent::handle();
if (empty($this->target)) {
// TRANS: Client error displayed when checking group membership for a non-existing user.
$this->clientError(_('No such user.'), 404);
}
if (empty($this->group)) {
// TRANS: Client error displayed when checking group membership for a non-existing group.
$this->clientError(_('Group not found.'), 404);
}
$is_member = $this->target->isMember($this->group);
switch($this->format) {
case 'xml':
$this->initDocument('xml');
$this->element('is_member', null, $is_member);
$this->endDocument('xml');
break;
case 'json':
$this->initDocument('json');
$this->showJsonObjects(array('is_member' => $is_member));
$this->endDocument('json');
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'));
}
}
/**
* Return true if read only.
*
* MAY override
*
* @param array $args other arguments
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
return true;
}
}

View File

@@ -1,124 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Join a group via the API
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Joins the authenticated user to the group speicified by ID
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiGroupJoinAction extends ApiAuthAction
{
protected $needPost = true;
var $group = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->group = $this->getTargetGroup($this->arg('id'));
return true;
}
/**
* Handle the request
*
* Join the authenticated user to the group
*
* @return void
*/
protected function handle()
{
parent::handle();
if (empty($this->scoped)) {
// TRANS: Client error displayed when trying to have a non-existing user join a group.
$this->clientError(_('No such user.'), 404);
}
if (empty($this->group)) {
// TRANS: Client error displayed when trying to join a group that does not exist.
$this->clientError(_('Group not found.'), 404);
}
if ($this->scoped->isMember($this->group)) {
// TRANS: Server error displayed when trying to join a group the user is already a member of.
$this->clientError(_('You are already a member of that group.'), 403);
}
if (Group_block::isBlocked($this->group, $this->scoped)) {
// TRANS: Server error displayed when trying to join a group the user is blocked from joining.
$this->clientError(_('You have been blocked from that group by the admin.'), 403);
}
try {
$this->scoped->joinGroup($this->group);
} catch (Exception $e) {
// TRANS: Server error displayed when joining a group failed in the database.
// TRANS: %1$s is the joining user's nickname, $2$s is the group nickname for which the join failed.
$this->serverError(sprintf(_('Could not join user %1$s to group %2$s.'),
$this->scoped->nickname, $this->group->nickname));
}
switch($this->format) {
case 'xml':
$this->showSingleXmlGroup($this->group);
break;
case 'json':
$this->showSingleJsonGroup($this->group);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
}

View File

@@ -1,123 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Leave a group via the API
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Removes the authenticated user from the group specified by ID
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiGroupLeaveAction extends ApiAuthAction
{
protected $needPost = true;
var $group = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->group = $this->getTargetGroup($this->arg('id'));
return true;
}
/**
* Handle the request
*
* Save the new message
*
* @return void
*/
protected function handle()
{
parent::handle();
if (!$this->scoped instanceof Profile) {
// TRANS: Client error displayed when trying to have a non-existing user leave a group.
$this->clientError(_('No such user.'), 404);
}
if (!$this->group instanceof User_group) {
// TRANS: Client error displayed when trying to leave a group that does not exist.
$this->clientError(_('Group not found.'), 404);
}
$member = new Group_member();
$member->group_id = $this->group->id;
$member->profile_id = $this->scoped->id;
if (!$member->find(true)) {
// TRANS: Server error displayed when trying to leave a group the user is not a member of.
$this->serverError(_('You are not a member of this group.'));
}
try {
$this->user->leaveGroup($this->group);
} catch (Exception $e) {
// TRANS: Server error displayed when leaving a group failed in the database.
// TRANS: %1$s is the leaving user's nickname, $2$s is the group nickname for which the leave failed.
$this->serverError(sprintf(_('Could not remove user %1$s from group %2$s.'),
$this->scoped->getNickname(), $this->group->nickname));
}
switch($this->format) {
case 'xml':
$this->showSingleXmlGroup($this->group);
break;
case 'json':
$this->showSingleJsonGroup($this->group);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
}

View File

@@ -1,211 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Check to see whether a user a member of a group
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Returns whether a user is a member of a specified group.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiGroupListAction extends ApiBareAuthAction
{
var $groups = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
//TODO: Make sure this doesn't leak unwantedly for federated users
$this->target = $this->getTargetProfile(null);
if (!($this->target instanceof Profile)) {
// TRANS: Client error displayed when user not found for an action.
$this->clientError(_('No such user.'), 404);
}
$this->groups = $this->getGroups();
return true;
}
/**
* Handle the request
*
* Show the user's groups
*
* @return void
*/
protected function handle()
{
parent::handle();
$sitename = common_config('site', 'name');
// TRANS: Used as title in check for group membership. %s is a user name.
$title = sprintf(_("%s's groups"), $this->target->nickname);
$taguribase = TagURI::base();
$id = "tag:$taguribase:Groups";
$link = common_local_url(
'usergroups',
array('nickname' => $this->target->nickname)
);
$subtitle = sprintf(
// TRANS: Used as subtitle in check for group membership. %1$s is the site name, %2$s is a user name.
_('%1$s groups %2$s is a member of.'),
$sitename,
$this->target->nickname
);
switch($this->format) {
case 'xml':
$this->showXmlGroups($this->groups);
break;
case 'rss':
$this->showRssGroups($this->groups, $title, $link, $subtitle);
break;
case 'atom':
$selfuri = common_local_url('ApiGroupList', array('id'=>$this->target->id, 'format'=>'atom'));
$this->showAtomGroups(
$this->groups,
$title,
$id,
$link,
$subtitle,
$selfuri
);
break;
case 'json':
$this->showJsonGroups($this->groups);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
/**
* Get groups
*
* @return array groups
*/
function getGroups()
{
$groups = array();
$group = $this->target->getGroups(
($this->page - 1) * $this->count,
$this->count,
$this->since_id,
$this->max_id
);
while ($group->fetch()) {
$groups[] = clone($group);
}
return $groups;
}
/**
* Is this action read only?
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* When was this feed last modified?
*
* @return string datestamp of the latest group the user has joined
*/
function lastModified()
{
if (!empty($this->groups) && (count($this->groups) > 0)) {
return strtotime($this->groups[0]->created);
}
return null;
}
/**
* An entity tag for this list of groups
*
* Returns an Etag based on the action name, language, user ID and
* timestamps of the first and last group the user has joined
*
* @return string etag
*/
function etag()
{
if (!empty($this->groups) && (count($this->groups) > 0)) {
$last = count($this->groups) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
$this->target->id,
strtotime($this->groups[0]->created),
strtotime($this->groups[$last]->created))
)
. '"';
}
return null;
}
}

View File

@@ -1,208 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show the newest groups
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Returns of the lastest 20 groups for the site
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiGroupListAllAction extends ApiPrivateAuthAction
{
var $groups = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
function prepare(array $args = array())
{
parent::prepare($args);
$this->user = $this->getTargetUser(null);
$this->groups = $this->getGroups();
return true;
}
/**
* Handle the request
*
* Show the user's groups
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
function handle()
{
parent::handle();
$sitename = common_config('site', 'name');
// TRANS: Message is used as a title when listing the lastest 20 groups. %s is a site name.
$title = sprintf(_("%s groups"), $sitename);
$taguribase = TagURI::base();
$id = "tag:$taguribase:Groups";
$link = common_local_url('groups');
// TRANS: Message is used as a subtitle when listing the latest 20 groups. %s is a site name.
$subtitle = sprintf(_("groups on %s"), $sitename);
switch($this->format) {
case 'xml':
$this->showXmlGroups($this->groups);
break;
case 'rss':
$this->showRssGroups($this->groups, $title, $link, $subtitle);
break;
case 'atom':
$selfuri = common_root_url() .
'api/statusnet/groups/list_all.atom';
$this->showAtomGroups(
$this->groups,
$title,
$id,
$link,
$subtitle,
$selfuri
);
break;
case 'json':
$this->showJsonGroups($this->groups);
break;
default:
$this->clientError(
// TRANS: Client error displayed when coming across a non-supported API method.
_('API method not found.'),
404,
$this->format
);
break;
}
}
/**
* Get groups
*
* @return array groups
*/
function getGroups()
{
$qry = 'SELECT user_group.* '.
'from user_group join local_group on user_group.id = local_group.group_id '.
'order by created desc ';
$offset = intval($this->page - 1) * intval($this->count);
$limit = intval($this->count);
if (common_config('db', 'type') == 'pgsql') {
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
} else {
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
}
$group = new User_group();
$group->query($qry);
$groups = array();
while ($group->fetch()) {
$groups[] = clone($group);
}
return $groups;
}
/**
* Is this action read only?
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* When was this feed last modified?
*
* @return string datestamp of the site's latest group
*/
function lastModified()
{
if (!empty($this->groups) && (count($this->groups) > 0)) {
return strtotime($this->groups[0]->created);
}
return null;
}
/**
* An entity tag for this list of groups
*
* Returns an Etag based on the action name, language, and
* timestamps of the first and last group the user has joined
*
* @return string etag
*/
function etag()
{
if (!empty($this->groups) && (count($this->groups) > 0)) {
$last = count($this->groups) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
strtotime($this->groups[0]->created),
strtotime($this->groups[$last]->created))
)
. '"';
}
return null;
}
}

View File

@@ -1,181 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* List a group's members
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* List 20 newest members of the group specified by name or ID.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiGroupMembershipAction extends ApiPrivateAuthAction
{
var $group = null;
var $profiles = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->group = $this->getTargetGroup($this->arg('id'));
if (empty($this->group)) {
// TRANS: Client error displayed trying to show group membership on a non-existing group.
$this->clientError(_('Group not found.'), 404);
}
$this->profiles = $this->getProfiles();
return true;
}
/**
* Handle the request
*
* Show the members of the group
*
* @return void
*/
protected function handle()
{
parent::handle();
// XXX: RSS and Atom
switch($this->format) {
case 'xml':
$this->showTwitterXmlUsers($this->profiles);
break;
case 'json':
$this->showJsonUsers($this->profiles);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
/**
* Fetch the members of a group
*
* @return array $profiles list of profiles
*/
function getProfiles()
{
$profiles = array();
$profile = $this->group->getMembers(
($this->page - 1) * $this->count,
$this->count,
$this->since_id,
$this->max_id
);
while ($profile->fetch()) {
$profiles[] = clone($profile);
}
return $profiles;
}
/**
* Is this action read only?
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* When was this list of profiles last modified?
*
* @return string datestamp of the lastest profile in the group
*/
function lastModified()
{
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
return strtotime($this->profiles[0]->created);
}
return null;
}
/**
* An entity tag for this list of groups
*
* Returns an Etag based on the action name, language
* the group id, and timestamps of the first and last
* user who has joined the group
*
* @return string etag
*/
function etag()
{
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
$last = count($this->profiles) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
$this->group->id,
strtotime($this->profiles[0]->created),
strtotime($this->profiles[$last]->created))
)
. '"';
}
return null;
}
}

View File

@@ -1,247 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Update a group's profile
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* API analog to the group edit page
*
* @category API
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiGroupProfileUpdateAction extends ApiAuthAction
{
protected $needPost = true;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->nickname = Nickname::normalize($this->trimmed('nickname'));
$this->fullname = $this->trimmed('fullname');
$this->homepage = $this->trimmed('homepage');
$this->description = $this->trimmed('description');
$this->location = $this->trimmed('location');
$this->aliasstring = $this->trimmed('aliases');
$this->user = $this->auth_user;
$this->group = $this->getTargetGroup($this->arg('id'));
return true;
}
/**
* Handle the request
*
* See which request params have been set, and update the profile
*
* @return void
*/
protected function handle()
{
parent::handle();
if (!in_array($this->format, array('xml', 'json'))) {
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
if (empty($this->user)) {
// TRANS: Client error displayed when not providing a user or an invalid user.
$this->clientError(_('No such user.'), 404);
}
if (empty($this->group)) {
// TRANS: Client error displayed when not providing a group or an invalid group.
$this->clientError(_('Group not found.'), 404);
}
if (!$this->user->isAdmin($this->group)) {
// TRANS: Client error displayed when trying to edit a group without being an admin.
$this->clientError(_('You must be an admin to edit the group.'), 403);
}
$this->group->query('BEGIN');
$orig = clone($this->group);
try {
if (common_config('profile', 'changenick') == true && $this->group->nickname !== $this->nickname) {
try {
$this->group->nickname = Nickname::normalize($this->nickname, true);
} catch (NicknameException $e) {
throw new ApiValidationException($e->getMessage());
}
$this->group->mainpage = common_local_url('showgroup',
array('nickname' => $this->group->nickname));
}
if (!empty($this->fullname)) {
$this->validateFullname();
$this->group->fullname = $this->fullname;
}
if (!empty($this->homepage)) {
$this->validateHomepage();
$this->group->homepage = $this->homepage;
}
if (!empty($this->description)) {
$this->validateDescription();
$this->group->description = $this->decription;
}
if (!empty($this->location)) {
$this->validateLocation();
$this->group->location = $this->location;
}
} catch (ApiValidationException $ave) {
$this->clientError($ave->getMessage(), 400);
}
$result = $this->group->update($orig);
if (!$result) {
common_log_db_error($this->group, 'UPDATE', __FILE__);
// TRANS: Server error displayed when group update fails.
$this->serverError(_('Could not update group.'));
}
$aliases = array();
try {
if (!empty($this->aliasstring)) {
$aliases = $this->validateAliases();
}
} catch (ApiValidationException $ave) {
$this->clientError($ave->getMessage(), 403);
}
$result = $this->group->setAliases($aliases);
if (!$result) {
// TRANS: Server error displayed when adding group aliases fails.
$this->serverError(_('Could not create aliases.'));
}
$this->group->query('COMMIT');
switch($this->format) {
case 'xml':
$this->showSingleXmlGroup($this->group);
break;
case 'json':
$this->showSingleJsonGroup($this->group);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
function validateHomepage()
{
if (!is_null($this->homepage)
&& (strlen($this->homepage) > 0)
&& !common_valid_http_url($this->homepage)) {
throw new ApiValidationException(
// TRANS: API validation exception thrown when homepage URL does not validate.
_('Homepage is not a valid URL.')
);
}
}
function validateFullname()
{
if (!is_null($this->fullname) && mb_strlen($this->fullname) > 255) {
throw new ApiValidationException(
// TRANS: API validation exception thrown when full name does not validate.
_('Full name is too long (maximum 255 characters).')
);
}
}
function validateDescription()
{
if (User_group::descriptionTooLong($this->description)) {
// TRANS: API validation exception thrown when description does not validate.
// TRANS: %d is the maximum description length and used for plural.
throw new ApiValidationException(sprintf(_m('Description is too long (maximum %d character).',
'Description is too long (maximum %d characters).',
User_group::maxDescription()),
User_group::maxDescription()));
}
}
function validateLocation()
{
if (!is_null($this->location) && mb_strlen($this->location) > 255) {
throw new ApiValidationException(
// TRANS: API validation exception thrown when location does not validate.
_('Location is too long (maximum 255 characters).')
);
}
}
function validateAliases()
{
try {
$aliases = array_map(array('Nickname', 'normalize'),
array_unique(preg_split('/[\s,]+/', $this->aliasstring)));
} catch (NicknameException $e) {
throw new ApiValidationException(sprintf('Error processing aliases: %s', $e->getMessage()));
}
if (count($aliases) > common_config('group', 'maxaliases')) {
// TRANS: API validation exception thrown when aliases do not validate.
// TRANS: %d is the maximum number of aliases and used for plural.
throw new ApiValidationException(sprintf(_m('Too many aliases! Maximum %d allowed.',
'Too many aliases! Maximum %d allowed.',
common_config('group', 'maxaliases')),
common_config('group', 'maxaliases')));
}
return $aliases;
}
}

View File

@@ -1,163 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show information about a group
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Outputs detailed information about the group specified by ID
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @author Michele <macno@macno.org>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiGroupShowAction extends ApiPrivateAuthAction
{
var $group = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->group = $this->getTargetGroup($this->arg('id'));
if (empty($this->group)) {
$alias = Group_alias::getKV(
'alias',
common_canonical_nickname($this->arg('id'))
);
if (!empty($alias)) {
$args = array('id' => $alias->group_id, 'format' => $this->format);
common_redirect(common_local_url('ApiGroupShow', $args), 301);
} else {
// TRANS: Client error displayed when trying to show a group that could not be found.
$this->clientError(_('Group not found.'), 404);
}
return;
}
return true;
}
/**
* Handle the request
*
* Check the format and show the user info
*
* @return void
*/
protected function handle()
{
parent::handle();
switch($this->format) {
case 'xml':
$this->showSingleXmlGroup($this->group);
break;
case 'json':
$this->showSingleJsonGroup($this->group);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
/**
* When was this group last modified?
*
* @return string datestamp of the latest notice in the stream
*/
function lastModified()
{
if (!empty($this->group)) {
return strtotime($this->group->modified);
}
return null;
}
/**
* An entity tag for this group
*
* Returns an Etag based on the action name, language, and
* timestamps of the notice
*
* @return string etag
*/
function etag()
{
if (!empty($this->group)) {
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
$this->group->id,
strtotime($this->group->modified))
)
. '"';
}
return null;
}
/**
* Return true if read only.
*
* MAY override
*
* @param array $args other arguments
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
return true;
}
}

View File

@@ -1,76 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Test that you can connect to the API
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Returns the string "ok" in the requested format with a 200 OK HTTP status code.
*
* @category API
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiHelpTestAction extends ApiPrivateAuthAction
{
protected function handle()
{
parent::handle();
if ($this->format == 'xml') {
$this->initDocument('xml');
$this->element('ok', null, 'true');
$this->endDocument('xml');
} elseif ($this->format == 'json') {
$this->initDocument('json');
print '"ok"';
$this->endDocument('json');
} else {
// TRANS: Client error displayed when coming across a non-supported API method.
throw new ClientException(_('API method not found.'), 404);
}
}
/**
* Return true if read only.
*
* MAY override
*
* @param array $args other arguments
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
return true;
}
}

View File

@@ -1,240 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show, update or delete a list.
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Shashi Gowda <connect2shashi@gmail.com>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
class ApiListAction extends ApiBareAuthAction
{
/**
* The list in question in the current request
*/
var $list = null;
/**
* Is this an update request?
*/
var $update = false;
/**
* Is this a delete request?
*/
var $delete = false;
/**
* Set the flags for handling the request. Show list if this is a GET
* request, update it if it is POST, delete list if method is DELETE
* or if method is POST and an argument _method is set to DELETE. Act
* like we don't know if the current user has no access to the list.
*
* Takes parameters:
* - user: the user id or nickname
* - id: the id of the tag or the tag itself
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->delete = ($_SERVER['REQUEST_METHOD'] == 'DELETE' ||
($this->trimmed('_method') == 'DELETE' &&
$_SERVER['REQUEST_METHOD'] == 'POST'));
// update list if method is POST or PUT and $this->delete is not true
$this->update = (!$this->delete &&
in_array($_SERVER['REQUEST_METHOD'], array('POST', 'PUT')));
$this->user = $this->getTargetUser($this->arg('user'));
$this->list = $this->getTargetList($this->arg('user'), $this->arg('id'));
if (empty($this->list)) {
// TRANS: Client error displayed when referring to a non-existing list.
$this->clientError(_('List not found.'), 404);
}
return true;
}
/**
* Handle the request
*
* @return boolean success flag
*/
protected function handle()
{
parent::handle();
if($this->delete) {
$this->handleDelete();
return true;
}
if($this->update) {
$this->handlePut();
return true;
}
switch($this->format) {
case 'xml':
$this->showSingleXmlList($this->list);
break;
case 'json':
$this->showSingleJsonList($this->list);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
/**
* require authentication if it is a write action or user is ambiguous
*
*/
function requiresAuth()
{
return parent::requiresAuth() ||
$this->create || $this->delete;
}
/**
* Update a list
*
* @return boolean success
*/
function handlePut()
{
if($this->auth_user->id != $this->list->tagger) {
// TRANS: Client error displayed when trying to update another user's list.
$this->clientError(_('You cannot update lists that do not belong to you.'), 401);
}
$new_list = clone($this->list);
$new_list->tag = common_canonical_tag($this->arg('name'));
$new_list->description = common_canonical_tag($this->arg('description'));
$new_list->private = ($this->arg('mode') === 'private') ? true : false;
$result = $new_list->update($this->list);
if(!$result) {
// TRANS: Client error displayed when an unknown error occurs updating a list.
$this->clientError(_('An error occured.'), 503);
}
switch($this->format) {
case 'xml':
$this->showSingleXmlList($new_list);
break;
case 'json':
$this->showSingleJsonList($new_list);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
/**
* Delete a list
*
* @return boolean success
*/
function handleDelete()
{
if($this->auth_user->id != $this->list->tagger) {
// TRANS: Client error displayed when trying to delete another user's list.
$this->clientError(_('You cannot delete lists that do not belong to you.'), 401);
}
$record = clone($this->list);
$this->list->delete();
switch($this->format) {
case 'xml':
$this->showSingleXmlList($record);
break;
case 'json':
$this->showSingleJsonList($record);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
/**
* Indicate that this resource is not read-only.
*
* @return boolean is_read-only=false
*/
function isReadOnly($args)
{
return false;
}
/**
* When was the list (people tag) last updated?
*
* @return String time_last_modified
*/
function lastModified()
{
if(!empty($this->list)) {
return strtotime($this->list->modified);
}
return null;
}
/**
* An entity tag for this list
*
* Returns an Etag based on the action name, language, user ID and
* timestamps of the first and last list the user has joined
*
* @return string etag
*/
function etag()
{
if (!empty($this->list)) {
return '"' . implode(
':',
array($this->arg('action'),
common_language(),
$this->user->id,
strtotime($this->list->created),
strtotime($this->list->modified))
)
. '"';
}
return null;
}
}

View File

@@ -1,112 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* API method to check if a user belongs to a list.
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Shashi Gowda <connect2shashi@gmail.com>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Action handler for Twitter list_memeber methods
*
* @category API
* @package StatusNet
* @author Shashi Gowda <connect2shashi@gmail.com>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
* @see ApiBareAuthAction
*/
class ApiListMemberAction extends ApiBareAuthAction
{
/**
* Set the flags for handling the request. Show the profile if this
* is a GET request AND the profile is a member of the list, add a member
* if it is a POST, remove the profile from the list if method is DELETE
* or if method is POST and an argument _method is set to DELETE. Act
* like we don't know if the current user has no access to the list.
*
* Takes parameters:
* - user: the user id or nickname
* - list_id: the id of the tag or the tag itself
* - id: the id of the member being looked for/added/removed
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->target = $this->getTargetProfile($this->arg('id'));
$this->list = $this->getTargetList($this->arg('user'), $this->arg('list_id'));
if (empty($this->list)) {
// TRANS: Client error displayed when referring to a non-existing list.
$this->clientError(_('List not found.'), 404);
}
if (!($this->target instanceof Profile)) {
// TRANS: Client error displayed when referring to a non-existing user.
$this->clientError(_('No such user.'), 404);
}
return true;
}
/**
* Handle the request
*
* @return boolean success flag
*/
protected function handle()
{
parent::handle();
$arr = array('tagger' => $this->list->tagger,
'tag' => $this->list->tag,
'tagged' => $this->target->id);
$ptag = Profile_tag::pkeyGet($arr);
if(empty($ptag)) {
// TRANS: Client error displayed when referring to a non-list member.
$this->clientError(_('The specified user is not a member of this list.'));
}
$user = $this->twitterUserArray($this->target, true);
switch($this->format) {
case 'xml':
$this->showTwitterXmlUser($user, 'user', true);
break;
case 'json':
$this->showSingleJsonUser($user);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
return true;
}
}

View File

@@ -1,131 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* List/add/remove list members.
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Shashi Gowda <connect2shashi@gmail.com>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
require_once INSTALLDIR . '/lib/apilistusers.php';
class ApiListMembersAction extends ApiListUsersAction
{
/**
* Add a user to a list (tag someone)
*
* @return boolean success
*/
function handlePost()
{
if($this->auth_user->id != $this->list->tagger) {
// TRANS: Client error displayed when trying to add members to a list without having the right to do so.
$this->clientError(_('You are not allowed to add members to this list.'), 401);
}
if (!($this->target instanceof Profile)) {
// TRANS: Client error displayed when trying to modify list members without specifying them.
$this->clientError(_('You must specify a member.'));
}
$result = Profile_tag::setTag($this->auth_user->id,
$this->target->id, $this->list->tag);
if(empty($result)) {
// TRANS: Client error displayed when an unknown error occurs viewing list members.
$this->clientError(_('An error occured.'), 500);
}
switch($this->format) {
case 'xml':
$this->showSingleXmlList($this->list);
break;
case 'json':
$this->showSingleJsonList($this->list);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
/**
* Remove a user from a list (untag someone)
*
* @return boolean success
*/
function handleDelete()
{
if($this->auth_user->id != $this->list->tagger) {
// TRANS: Client error displayed when trying to remove members from a list without having the right to do so.
$this->clientError(_('You are not allowed to remove members from this list.'), 401);
}
if (!($this->target instanceof Profile)) {
// TRANS: Client error displayed when trying to modify list members without specifying them.
$this->clientError(_('You must specify a member.'));
}
$args = array('tagger' => $this->auth_user->id,
'tagged' => $this->target->id,
'tag' => $this->list->tag);
$ptag = Profile_tag::pkeyGet($args);
if (empty($ptag)) {
// TRANS: Client error displayed when trying to remove a list member that is not part of a list.
$this->clientError(_('The user you are trying to remove from the list is not a member.'));
}
if (!$ptag->delete()) {
// TRANS: Client error displayed when an unknown error occurs viewing list members.
$this->clientError(_('An error occured.'), 500);
}
switch($this->format) {
case 'xml':
$this->showSingleXmlList($this->list);
break;
case 'json':
$this->showSingleJsonList($this->list);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
return true;
}
/**
* List the members of a list (people tagged)
*/
function getUsers()
{
$fn = array($this->list, 'getTagged');
list($this->users, $this->next_cursor, $this->prev_cursor) =
Profile_list::getAtCursor($fn, array(), $this->cursor, 20);
}
}

View File

@@ -1,124 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Get a list of lists a user belongs to. (people tags for a user)
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Shashi Gowda <connect2shashi@gmail.com>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Action handler for API method to list lists a user belongs to.
* (people tags for a user)
*
* @category API
* @package StatusNet
* @author Shashi Gowda <connect2shashi@gmail.com>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
* @see ApiBareAuthAction
*/
class ApiListMembershipsAction extends ApiBareAuthAction
{
var $lists = array();
var $cursor = -1;
var $next_cursor = 0;
var $prev_cursor = 0;
/**
* Prepare for running the action
* Take arguments for running:s
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->cursor = (int) $this->arg('cursor', -1);
$user = $this->getTargetUser($this->arg('user'));
if (!($user instanceof User)) {
// TRANS: Client error displayed trying to perform an action related to a non-existing user.
$this->clientError(_('No such user.'), 404);
}
$this->target = $user->getProfile();
$this->getLists();
return true;
}
/**
* Handle the request
*
* Show the lists
*
* @return void
*/
protected function handle()
{
parent::handle();
switch($this->format) {
case 'xml':
$this->showXmlLists($this->lists, $this->next_cursor, $this->prev_cursor);
break;
case 'json':
$this->showJsonLists($this->lists, $this->next_cursor, $this->prev_cursor);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'));
}
}
/**
* Return true if read only.
*
* MAY override
*
* @param array $args other arguments
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
return true;
}
function getLists()
{
$fn = array($this->target, 'getOtherTags');
# 20 lists
list($this->lists, $this->next_cursor, $this->prev_cursor) =
Profile_list::getAtCursor($fn, array($this->scoped), $this->cursor, 20);
}
}

View File

@@ -1,232 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* List existing lists or create a new list.
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Shashi Gowda <connect2shashi@gmail.com>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Action handler for Twitter list_memeber methods
*
* @category API
* @package StatusNet
* @author Shashi Gowda <connect2shashi@gmail.com>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
* @see ApiBareAuthAction
*/
class ApiListsAction extends ApiBareAuthAction
{
var $lists = null;
var $cursor = 0;
var $next_cursor = 0;
var $prev_cursor = 0;
var $create = false;
/**
* Set the flags for handling the request. List lists created by user if this
* is a GET request, create a new list if it is a POST request.
*
* Takes parameters:
* - user: the user id or nickname
* Parameters for POST request
* - name: name of the new list (the people tag itself)
* - mode: (optional) mode for the new list private/public
* - description: (optional) description for the list
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->create = ($_SERVER['REQUEST_METHOD'] == 'POST');
if (!$this->create) {
$this->user = $this->getTargetUser($this->arg('user'));
if (!($user instanceof User)) {
// TRANS: Client error displayed trying to perform an action related to a non-existing user.
$this->clientError(_('No such user.'), 404);
}
$this->target = $user->getProfile();
$this->getLists();
}
return true;
}
/**
* require authentication if it is a write action or user is ambiguous
*
*/
function requiresAuth()
{
return parent::requiresAuth() ||
$this->create || $this->delete;
}
/**
* Handle request:
* Show the lists the user has created if the request method is GET
* Create a new list by diferring to handlePost() if it is POST.
*/
protected function handle()
{
parent::handle();
if($this->create) {
return $this->handlePost();
}
switch($this->format) {
case 'xml':
$this->showXmlLists($this->lists, $this->next_cursor, $this->prev_cursor);
break;
case 'json':
$this->showJsonLists($this->lists, $this->next_cursor, $this->prev_cursor);
break;
default:
$this->clientError(
// TRANS: Client error displayed when coming across a non-supported API method.
_('API method not found.'),
404,
$this->format
);
break;
}
}
/**
* Create a new list
*
* @return boolean success
*/
function handlePost()
{
$name=$this->arg('name');
if(empty($name)) {
// mimick twitter
// TRANS: Client error displayed when trying to create a list without a name.
print _("A list must have a name.");
exit(1);
}
// twitter creates a new list by appending a number to the end
// if the list by the given name already exists
// it makes more sense to return the existing list instead
$private = null;
if ($this->arg('mode') === 'public') {
$private = false;
} else if ($this->arg('mode') === 'private') {
$private = true;
}
$list = Profile_list::ensureTag($this->auth_user->id,
$this->arg('name'),
$this->arg('description'),
$private);
if (empty($list)) {
return false;
}
switch($this->format) {
case 'xml':
$this->showSingleXmlList($list);
break;
case 'json':
$this->showSingleJsonList($list);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
return true;
}
/**
* Get lists
*/
function getLists()
{
$cursor = (int) $this->arg('cursor', -1);
// twitter fixes count at 20
// there is no argument named count
$count = 20;
$fn = array($this->target, 'getLists');
list($this->lists,
$this->next_cursor,
$this->prev_cursor) = Profile_list::getAtCursor($fn, array($this->scoped), $cursor, $count);
}
function isReadOnly($args)
{
return false;
}
function lastModified()
{
if (!$this->create && !empty($this->lists) && (count($this->lists) > 0)) {
return strtotime($this->lists[0]->created);
}
return null;
}
/**
* An entity tag for this list of lists
*
* Returns an Etag based on the action name, language, user ID and
* timestamps of the first and last list the user has joined
*
* @return string etag
*/
function etag()
{
if (!$this->create && !empty($this->lists) && (count($this->lists) > 0)) {
$last = count($this->lists) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_language(),
$this->target->id,
strtotime($this->lists[0]->created),
strtotime($this->lists[$last]->created))
)
. '"';
}
return null;
}
}

View File

@@ -1,87 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Check if a user is subscribed to a list
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
class ApiListSubscriberAction extends ApiBareAuthAction
{
var $list = null;
function prepare(array $args = array())
{
parent::prepare($args);
$this->target = $this->getTargetProfile($this->arg('id'));
$this->list = $this->getTargetList($this->arg('user'), $this->arg('list_id'));
if (empty($this->list)) {
// TRANS: Client error displayed trying to perform an action related to a non-existing list.
$this->clientError(_('List not found.'), 404);
}
if (!($this->target instanceof Profile)) {
// TRANS: Client error displayed trying to perform an action related to a non-existing user.
$this->clientError(_('No such user.'), 404);
}
return true;
}
function handle()
{
parent::handle();
$arr = array('profile_tag_id' => $this->list->id,
'profile_id' => $this->target->id);
$sub = Profile_tag_subscription::pkeyGet($arr);
if(empty($sub)) {
// TRANS: Client error displayed when a membership check for a user is nagative.
$this->clientError(_('The specified user is not a subscriber of this list.'));
}
$user = $this->twitterUserArray($this->target, true);
switch($this->format) {
case 'xml':
$this->showTwitterXmlUser($user, 'user', true);
break;
case 'json':
$this->showSingleJsonUser($user);
break;
default:
$this->clientError(
// TRANS: Client error displayed when coming across a non-supported API method.
_('API method not found.'),
404,
$this->format
);
break;
}
}
}

View File

@@ -1,102 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show/add/remove list subscribers.
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
require_once INSTALLDIR . '/lib/apilistusers.php';
class ApiListSubscribersAction extends ApiListUsersAction
{
/**
* Subscribe to list
*
* @return boolean success
*/
function handlePost()
{
$result = Profile_tag_subscription::add($this->list,
$this->auth_user);
if(empty($result)) {
// TRANS: Client error displayed when an unknown error occurs in the list subscribers action.
$this->clientError(_('An error occured.'), 500);
}
switch($this->format) {
case 'xml':
$this->showSingleXmlList($this->list);
break;
case 'json':
$this->showSingleJsonList($this->list);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
function handleDelete()
{
$args = array('profile_tag_id' => $this->list->id,
'profile_id' => $this->auth_user->id);
$ptag = Profile_tag_subscription::pkeyGet($args);
if(empty($ptag)) {
// TRANS: Client error displayed when trying to unsubscribe from a non-subscribed list.
$this->clientError(_('You are not subscribed to this list.'));
}
$result = Profile_tag_subscription::remove($this->list, $this->auth_user);
if (empty($result)) {
// TRANS: Client error displayed when an unknown error occurs unsubscribing from a list.
$this->clientError(_('An error occured.'), 500);
}
switch($this->format) {
case 'xml':
$this->showSingleXmlList($this->list);
break;
case 'json':
$this->showSingleJsonList($this->list);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
return true;
}
function getUsers()
{
$fn = array($this->list, 'getSubscribers');
list($this->users, $this->next_cursor, $this->prev_cursor) =
Profile_list::getAtCursor($fn, array(), $this->cursor, 20);
}
}

View File

@@ -1,110 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Get a list of lists a user is subscribed to.
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
class ApiListSubscriptionsAction extends ApiBareAuthAction
{
var $lists = array();
var $cursor = -1;
var $next_cursor = 0;
var $prev_cursor = 0;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->cursor = (int) $this->arg('cursor', -1);
$user = $this->getTargetUser($this->arg('user'));
if (!($user instanceof User)) {
// TRANS: Client error displayed trying to perform an action related to a non-existing user.
$this->clientError(_('No such user.'), 404);
}
$this->target = $user->getProfile();
$this->getLists();
return true;
}
/**
* Handle the request
*
* Show the lists
*
* @return void
*/
protected function handle()
{
parent::handle();
switch($this->format) {
case 'xml':
$this->showXmlLists($this->lists, $this->next_cursor, $this->prev_cursor);
break;
case 'json':
$this->showJsonLists($this->lists, $this->next_cursor, $this->prev_cursor);
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'));
}
}
/**
* Return true if read only.
*
* MAY override
*
* @param array $args other arguments
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
return true;
}
function getLists()
{
$fn = array($this->target, 'getTagSubscriptions');
# 20 lists
list($this->lists, $this->next_cursor, $this->prev_cursor) =
Profile_list::getAtCursor($fn, array(), $this->cursor, 20);
}
}

View File

@@ -1,195 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Upload an image via the API
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Upload an image via the API. Returns a shortened URL for the image
* to the user. Apparently modelled after a former Twitpic API.
*
* @category API
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiMediaUploadAction extends ApiAuthAction
{
protected $needPost = true;
protected function prepare(array $args=array())
{
parent::prepare($args);
// fallback to xml for older clients etc
if (empty($this->format)) {
$this->format = 'xml';
}
if (!in_array($this->format, ['json', 'xml'])) {
throw new ClientException('This API call does not support the format '._ve($this->format));
}
return true;
}
protected function handle()
{
parent::handle();
// Workaround for PHP returning empty $_POST and $_FILES when POST
// length > post_max_size in php.ini
if (empty($_FILES)
&& empty($_POST)
&& ($_SERVER['CONTENT_LENGTH'] > 0)
) {
// TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit.
// TRANS: %s is the number of bytes of the CONTENT_LENGTH.
$msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.',
'The server was unable to handle that much POST data (%s bytes) due to its current configuration.',
intval($_SERVER['CONTENT_LENGTH']));
throw new ClientException(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
}
try {
$upload = MediaFile::fromUpload('media', $this->scoped);
} catch (NoUploadedMediaException $e) {
common_debug('No media file was uploaded to the _FILES array');
$fh = tmpfile();
if ($this->arg('media')) {
common_debug('Found media parameter which we hope contains a media file!');
fwrite($fh, $this->arg('media'));
} elseif ($this->arg('media_data')) {
common_debug('Found media_data parameter which we hope contains a base64-encoded media file!');
fwrite($fh, base64_decode($this->arg('media_data')));
} else {
common_debug('No media|media_data POST parameter was supplied');
fclose($fh);
throw $e;
}
common_debug('MediaFile importing the uploaded file with fromFilehandle');
$upload = MediaFile::fromFilehandle($fh, $this->scoped);
}
common_debug('MediaFile completed and saved us fileRecord with id=='._ve($upload->fileRecord->id));
// Thumbnails will be generated/cached on demand when accessed (such as with /attachment/:id/thumbnail)
$this->showResponse($upload);
}
/**
* Show a Twitpic-like response with the ID of the media file
* and a (hopefully) shortened URL for it.
*
* @param MediaFile $upload the uploaded file
*
* @return void
*/
protected function showResponse(MediaFile $upload)
{
$this->initDocument($this->format);
switch ($this->format) {
case 'json':
return $this->showResponseJson($upload);
case 'xml':
return $this->showResponseXml($upload);
default:
throw new ClientException('This API call does not support the format '._ve($this->format));
}
$this->endDocument($this->format);
}
protected function showResponseJson(MediaFile $upload)
{
$enc = $upload->fileRecord->getEnclosure();
// note that we use media_id instead of mediaid which XML users might've gotten used to (nowadays we service media_id in both!)
$output = [
'media_id' => $upload->fileRecord->id,
'media_id_string' => (string)$upload->fileRecord->id,
'media_url' => $upload->shortUrl(),
'size' => $upload->fileRecord->size,
];
if (common_get_mime_media($enc->mimetype) === 'image') {
$output['image'] = [
'w' => $enc->width,
'h' => $enc->height,
'image_type' => $enc->mimetype,
];
}
print json_encode($output);
}
protected function showResponseXml(MediaFile $upload)
{
$this->elementStart('rsp', array('stat' => 'ok', 'xmlns:atom'=>Activity::ATOM));
$this->element('mediaid', null, $upload->fileRecord->id);
$this->element('mediaurl', null, $upload->shortUrl());
$this->element('media_url', null, $upload->shortUrl());
$this->element('size', null, $upload->fileRecord->size);
$enclosure = $upload->fileRecord->getEnclosure();
$this->element('atom:link', array('rel' => 'enclosure',
'href' => $enclosure->url,
'type' => $enclosure->mimetype));
// Twitter specific metadata expected in response since Twitter's Media upload API v1.1 (even though Twitter doesn't use XML)
$this->element('media_id', null, $upload->fileRecord->id);
$this->element('media_id_string', null, (string)$upload->fileRecord->id);
if (common_get_mime_media($enclosure->mimetype) === 'image') {
$this->element('image', ['w'=>$enclosure->width, 'h'=>$enclosure->height, 'image_type'=>$enclosure->mimetype]);
}
$this->elementEnd('rsp');
}
/**
* Overrided clientError to show a more Twitpic-like error
*
* @param String $msg an error message
*/
function clientError($msg, $code=400, $format=null)
{
$this->initDocument($this->format);
switch ($this->format) {
case 'json':
$error = ['errors' => array()];
$error['errors'][] = ['message'=>$msg, 'code'=>131];
print json_encode($error);
break;
case 'xml':
$this->elementStart('rsp', array('stat' => 'fail'));
// @todo add in error code
$errAttr = array('msg' => $msg);
$this->element('err', $errAttr, null);
$this->elementEnd('rsp');
break;
}
$this->endDocument($this->format);
exit;
}
}

View File

@@ -1,122 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Action for getting OAuth token credentials (exchange an authorized
* request token for an access token)
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Action for getting OAuth token credentials (exchange an authorized
* request token for an access token)
*
* @category API
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiOAuthAccessTokenAction extends ApiOAuthAction
{
protected $reqToken = null;
protected $verifier = null;
/**
* Class handler.
*
* @param array $args array of arguments
*
* @return void
*/
function handle()
{
parent::handle();
$datastore = new ApiGNUsocialOAuthDataStore();
$server = new OAuthServer($datastore);
$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
$server->add_signature_method($hmac_method);
$atok = $app = null;
// XXX: Insist that oauth_token and oauth_verifier be populated?
// Spec doesn't say they MUST be.
try {
$req = OAuthRequest::from_request();
$this->reqToken = $req->get_parameter('oauth_token');
$this->verifier = $req->get_parameter('oauth_verifier');
$app = $datastore->getAppByRequestToken($this->reqToken);
$atok = $server->fetch_access_token($req);
} catch (Exception $e) {
common_log(LOG_WARNING, 'API OAuthException - ' . $e->getMessage());
common_debug(var_export($req, true));
$code = $e->getCode();
$this->clientError($e->getMessage(), empty($code) ? 401 : $code, 'text');
}
if (empty($atok)) {
// Token exchange failed -- log it
$msg = sprintf(
'API OAuth - Failure exchanging OAuth request token for access token, '
. 'request token = %s, verifier = %s',
$this->reqToken,
$this->verifier
);
common_log(LOG_WARNING, $msg);
// TRANS: Client error given from the OAuth API when the request token or verifier is invalid.
$this->clientError(_('Invalid request token or verifier.'), 400, 'text');
} else {
common_log(
LOG_INFO,
sprintf(
"Issued access token '%s' for application %d (%s).",
$atok->key,
$app->id,
$app->name
)
);
$this->showAccessToken($atok);
}
}
/*
* Display OAuth token credentials
*
* @param OAuthToken token the access token
*/
function showAccessToken($token)
{
header('Content-Type: application/x-www-form-urlencoded');
print $token;
}
}

View File

@@ -1,707 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Authorize an OAuth request token
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @copyright 2010-2011 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Authorize an OAuth request token
*
* @category API
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiOAuthAuthorizeAction extends ApiOAuthAction
{
var $oauthTokenParam;
var $reqToken;
var $callback;
var $app;
var $nickname;
var $password;
var $store;
/**
* Is this a read-only action?
*
* @return boolean false
*/
function isReadOnly($args)
{
return false;
}
function prepare(array $args = array())
{
parent::prepare($args);
$this->nickname = $this->trimmed('nickname');
$this->password = $this->arg('password');
$this->oauthTokenParam = $this->arg('oauth_token');
$this->mode = $this->arg('mode');
$this->store = new ApiGNUsocialOAuthDataStore();
try {
$this->app = $this->store->getAppByRequestToken($this->oauthTokenParam);
} catch (Exception $e) {
$this->clientError($e->getMessage());
}
return true;
}
/**
* Handle input, produce output
*
* Switches on request method; either shows the form or handles its input.
*
* @param array $args $_REQUEST data
*
* @return void
*/
function handle()
{
parent::handle();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$this->handlePost();
} else {
// Make sure a oauth_token parameter was provided
if (empty($this->oauthTokenParam)) {
// TRANS: Client error given when no oauth_token was passed to the OAuth API.
$this->clientError(_('No oauth_token parameter provided.'));
} else {
// Check to make sure the token exists
$this->reqToken = $this->store->getTokenByKey($this->oauthTokenParam);
if (empty($this->reqToken)) {
// TRANS: Client error given when an invalid request token was passed to the OAuth API.
$this->clientError(_('Invalid request token.'));
} else {
// Check to make sure we haven't already authorized the token
if ($this->reqToken->state != 0) {
// TRANS: Client error given when an invalid request token was passed to the OAuth API.
$this->clientError(_('Request token already authorized.'));
}
}
}
// make sure there's an app associated with this token
if (empty($this->app)) {
// TRANS: Client error given when an invalid request token was passed to the OAuth API.
$this->clientError(_('Invalid request token.'));
}
$name = $this->app->name;
$this->showForm();
}
}
function handlePost()
{
// check session token for CSRF protection.
$token = $this->trimmed('token');
if (!$token || $token != common_session_token()) {
$this->showForm(
// TRANS: Form validation error in API OAuth authorisation because of an invalid session token.
_('There was a problem with your session token. Try again, please.'));
return;
}
// check creds
$user = null;
if (!common_logged_in()) {
// XXX Force credentials check?
// @fixme this should probably use a unified login form handler
$user = null;
if (Event::handle('StartOAuthLoginCheck', array($this, &$user))) {
$user = common_check_user($this->nickname, $this->password);
}
Event::handle('EndOAuthLoginCheck', array($this, &$user));
if (empty($user)) {
// TRANS: Form validation error given when an invalid username and/or password was passed to the OAuth API.
$this->showForm(_("Invalid nickname / password!"));
return;
}
} else {
$user = common_current_user();
}
// fetch the token
$this->reqToken = $this->store->getTokenByKey($this->oauthTokenParam);
assert(!empty($this->reqToken));
if ($this->arg('allow')) {
// mark the req token as authorized
try {
$this->store->authorize_token($this->oauthTokenParam);
} catch (Exception $e) {
$this->serverError($e->getMessage());
}
common_log(
LOG_INFO,
sprintf(
"API OAuth - User %d (%s) has authorized request token %s for OAuth application %d (%s).",
$user->id,
$user->nickname,
$this->reqToken->tok,
$this->app->id,
$this->app->name
)
);
$tokenAssoc = new Oauth_token_association();
$tokenAssoc->profile_id = $user->id;
$tokenAssoc->application_id = $this->app->id;
$tokenAssoc->token = $this->oauthTokenParam;
$tokenAssoc->created = common_sql_now();
$result = $tokenAssoc->insert();
if (!$result) {
common_log_db_error($tokenAssoc, 'INSERT', __FILE__);
// TRANS: Server error displayed when a database action fails.
$this->serverError(_('Database error inserting oauth_token_association.'));
}
$callback = $this->getCallback();
if (!empty($callback) && $this->reqToken->verified_callback != 'oob') {
$targetUrl = $this->buildCallbackUrl(
$callback,
array(
'oauth_token' => $this->oauthTokenParam,
'oauth_verifier' => $this->reqToken->verifier // 1.0a
)
);
common_log(LOG_INFO, "Redirecting to callback: $targetUrl");
// Redirect the user to the provided OAuth callback
common_redirect($targetUrl, 303);
} elseif ($this->app->type == 2) {
// Strangely, a web application seems to want to do the OOB
// workflow. Because no callback was specified anywhere.
common_log(
LOG_WARNING,
sprintf(
"API OAuth - No callback provided for OAuth web client ID %s (%s) "
. "during authorization step. Falling back to OOB workflow.",
$this->app->id,
$this->app->name
)
);
}
// Otherwise, inform the user that the rt was authorized
$this->showAuthorized();
} else if ($this->arg('cancel')) {
common_log(
LOG_INFO,
sprintf(
"API OAuth - User %d (%s) refused to authorize request token %s for OAuth application %d (%s).",
$user->id,
$user->nickname,
$this->reqToken->tok,
$this->app->id,
$this->app->name
)
);
try {
$this->store->revoke_token($this->oauthTokenParam, 0);
} catch (Exception $e) {
$this->ServerError($e->getMessage());
}
$callback = $this->getCallback();
// If there's a callback available, inform the consumer the user
// has refused authorization
if (!empty($callback) && $this->reqToken->verified_callback != 'oob') {
$targetUrl = $this->buildCallbackUrl(
$callback,
array(
'oauth_problem' => 'user_refused',
)
);
common_log(LOG_INFO, "Redirecting to callback: $targetUrl");
// Redirect the user to the provided OAuth callback
common_redirect($targetUrl, 303);
}
// otherwise inform the user that authorization for the rt was declined
$this->showCanceled();
} else {
// TRANS: Client error given on when invalid data was passed through a form in the OAuth API.
$this->clientError(_('Unexpected form submission.'));
}
}
/**
* Show body - override to add a special CSS class for the authorize
* page's "desktop mode" (minimal display)
*
* Calls template methods
*
* @return nothing
*/
function showBody()
{
$bodyClasses = array();
if ($this->desktopMode()) {
$bodyClasses[] = 'oauth-desktop-mode';
}
if (common_current_user()) {
$bodyClasses[] = 'user_in';
}
$attrs = array('id' => strtolower($this->trimmed('action')));
if (!empty($bodyClasses)) {
$attrs['class'] = implode(' ', $bodyClasses);
}
$this->elementStart('body', $attrs);
$this->elementStart('div', array('id' => 'wrap'));
if (Event::handle('StartShowHeader', array($this))) {
$this->showHeader();
Event::handle('EndShowHeader', array($this));
}
$this->showCore();
if (Event::handle('StartShowFooter', array($this))) {
$this->showFooter();
Event::handle('EndShowFooter', array($this));
}
$this->elementEnd('div');
$this->showScripts();
$this->elementEnd('body');
}
function showForm($error=null)
{
$this->error = $error;
$this->showPage();
}
function showScripts()
{
parent::showScripts();
if (!common_logged_in()) {
$this->autofocus('nickname');
}
}
/**
* Title of the page
*
* @return string title of the page
*/
function title()
{
// TRANS: Title for a page where a user can confirm/deny account access by an external application.
return _('An application would like to connect to your account');
}
/**
* Shows the authorization form.
*
* @return void
*/
function showContent()
{
$this->elementStart('form', array('method' => 'post',
'id' => 'form_apioauthauthorize',
'class' => 'form_settings',
'action' => common_local_url('ApiOAuthAuthorize')));
$this->elementStart('fieldset');
$this->element('legend', array('id' => 'apioauthauthorize_allowdeny'),
// TRANS: Fieldset legend.
_('Allow or deny access'));
$this->hidden('token', common_session_token());
$this->hidden('mode', $this->mode);
$this->hidden('oauth_token', $this->oauthTokenParam);
$this->hidden('oauth_callback', $this->callback);
$this->elementStart('ul', 'form_data');
$this->elementStart('li');
$this->elementStart('p');
if (!empty($this->app->icon) && $this->app->name != 'anonymous') {
$this->element('img', array('src' => $this->app->icon));
}
$access = ($this->app->access_type & Oauth_application::$writeAccess) ?
'access and update' : 'access';
if ($this->app->name == 'anonymous') {
// Special message for the anonymous app and consumer.
// TRANS: User notification of external application requesting account access.
// TRANS: %3$s is the access type requested (read-write or read-only), %4$s is the StatusNet sitename.
$msg = _('An application would like the ability ' .
'to <strong>%3$s</strong> your %4$s account data. ' .
'You should only give access to your %4$s account ' .
'to third parties you trust.');
} else {
// TRANS: User notification of external application requesting account access.
// TRANS: %1$s is the application name requesting access, %2$s is the organisation behind the application,
// TRANS: %3$s is the access type requested, %4$s is the StatusNet sitename.
$msg = _('The application <strong>%1$s</strong> by ' .
'<strong>%2$s</strong> would like the ability ' .
'to <strong>%3$s</strong> your %4$s account data. ' .
'You should only give access to your %4$s account ' .
'to third parties you trust.');
}
$this->raw(sprintf($msg,
$this->app->name,
$this->app->organization,
$access,
common_config('site', 'name')));
$this->elementEnd('p');
$this->elementEnd('li');
$this->elementEnd('ul');
// quickie hack
$button = false;
if (!common_logged_in()) {
if (Event::handle('StartOAuthLoginForm', array($this, &$button))) {
$this->elementStart('fieldset');
// TRANS: Fieldset legend.
$this->element('legend', null, _m('LEGEND','Account'));
$this->elementStart('ul', 'form_data');
$this->elementStart('li');
// TRANS: Field label on OAuth API authorisation form.
$this->input('nickname', _('Nickname'));
$this->elementEnd('li');
$this->elementStart('li');
// TRANS: Field label on OAuth API authorisation form.
$this->password('password', _('Password'));
$this->elementEnd('li');
$this->elementEnd('ul');
$this->elementEnd('fieldset');
}
Event::handle('EndOAuthLoginForm', array($this, &$button));
}
$this->element('input', array('id' => 'cancel_submit',
'class' => 'submit submit form_action-primary',
'name' => 'cancel',
'type' => 'submit',
// TRANS: Button text that when clicked will cancel the process of allowing access to an account
// TRANS: by an external application.
'value' => _m('BUTTON','Cancel')));
$this->element('input', array('id' => 'allow_submit',
'class' => 'submit submit form_action-secondary',
'name' => 'allow',
'type' => 'submit',
// TRANS: Button text that when clicked will allow access to an account by an external application.
'value' => $button ? $button : _m('BUTTON','Allow')));
$this->elementEnd('fieldset');
$this->elementEnd('form');
}
/**
* Instructions for using the form
*
* For "remembered" logins, we make the user re-login when they
* try to change settings. Different instructions for this case.
*
* @return void
*/
function getInstructions()
{
// TRANS: Form instructions.
return _('Authorize access to your account information.');
}
/**
* A local menu
*
* Shows different login/register actions.
*
* @return void
*/
function showLocalNav()
{
// NOP
}
/*
* Checks to see if a the "mode" parameter is present in the request
* and set to "desktop". If it is, the page is meant to be displayed in
* a small frame of another application, and we should suppress the
* header, aside, and footer.
*/
function desktopMode()
{
if (isset($this->mode) && $this->mode == 'desktop') {
return true;
} else {
return false;
}
}
/*
* Override - suppress output in "desktop" mode
*/
function showHeader()
{
if ($this->desktopMode() == false) {
parent::showHeader();
}
}
/*
* Override - suppress output in "desktop" mode
*/
function showAside()
{
if ($this->desktopMode() == false) {
parent::showAside();
}
}
/*
* Override - suppress output in "desktop" mode
*/
function showFooter()
{
if ($this->desktopMode() == false) {
parent::showFooter();
}
}
/**
* Show site notice.
*
* @return nothing
*/
function showSiteNotice()
{
// NOP
}
/**
* Show notice form.
*
* Show the form for posting a new notice
*
* @return nothing
*/
function showNoticeForm()
{
// NOP
}
/*
* Show a nice message confirming the authorization
* operation was canceled.
*
* @return nothing
*/
function showCanceled()
{
$info = new InfoAction(
// TRANS: Header for user notification after revoking OAuth access to an application.
_('Authorization canceled.'),
sprintf(
// TRANS: User notification after revoking OAuth access to an application.
// TRANS: %s is an OAuth token.
_('The request token %s has been revoked.'),
$this->oauthTokenParam
)
);
$info->showPage();
}
/*
* Show a nice message that the authorization was successful.
* If the operation is out-of-band, show a pin.
*
* @return nothing
*/
function showAuthorized()
{
$title = null;
$msg = null;
if ($this->app->name == 'anonymous') {
$title =
// TRANS: Title of the page notifying the user that an anonymous client application was successfully authorized to access the user's account with OAuth.
_('You have successfully authorized the application');
$msg =
// TRANS: Message notifying the user that an anonymous client application was successfully authorized to access the user's account with OAuth.
_('Please return to the application and enter the following security code to complete the process.');
} else {
$title = sprintf(
// TRANS: Title of the page notifying the user that the client application was successfully authorized to access the user's account with OAuth.
// TRANS: %s is the authorised application name.
_('You have successfully authorized %s'),
$this->app->name
);
$msg = sprintf(
// TRANS: Message notifying the user that the client application was successfully authorized to access the user's account with OAuth.
// TRANS: %s is the authorised application name.
_('Please return to %s and enter the following security code to complete the process.'),
$this->app->name
);
}
if ($this->reqToken->verified_callback == 'oob') {
$pin = new ApiOAuthPinAction(
$title,
$msg,
$this->reqToken->verifier,
$this->desktopMode()
);
$pin->showPage();
} else {
// NOTE: This would only happen if an application registered as
// a web application but sent in 'oob' for the oauth_callback
// parameter. Usually web apps will send in a callback and
// not use the pin-based workflow.
$info = new InfoAction(
$title,
$msg,
$this->oauthTokenParam,
$this->reqToken->verifier
);
$info->showPage();
}
}
/*
* Figure out what the callback should be
*/
function getCallback()
{
$callback = null;
// Return the verified callback if we have one
if ($this->reqToken->verified_callback != 'oob') {
$callback = $this->reqToken->verified_callback;
// Otherwise return the callback that was provided when
// registering the app
if (empty($callback)) {
common_debug(
"No verified callback found for request token, using application callback: "
. $this->app->callback_url,
__FILE__
);
$callback = $this->app->callback_url;
}
}
return $callback;
}
/*
* Properly format the callback URL and parameters so it's
* suitable for a redirect in the OAuth dance
*
* @param string $url the URL
* @param array $params an array of parameters
*
* @return string $url a URL to use for redirecting to
*/
function buildCallbackUrl($url, $params)
{
foreach ($params as $k => $v) {
$url = $this->appendQueryVar(
$url,
OAuthUtil::urlencode_rfc3986($k),
OAuthUtil::urlencode_rfc3986($v)
);
}
return $url;
}
/*
* Append a new query parameter after any existing query
* parameters.
*
* @param string $url the URL
* @prarm string $k the parameter name
* @param string $v value of the paramter
*
* @return string $url the new URL with added parameter
*/
function appendQueryVar($url, $k, $v) {
$url = preg_replace('/(.*)(\?|&)' . $k . '=[^&]+?(&)(.*)/i', '$1$2$4', $url . '&');
$url = substr($url, 0, -1);
if (strpos($url, '?') === false) {
return ($url . '?' . $k . '=' . $v);
} else {
return ($url . '&' . $k . '=' . $v);
}
}
}

View File

@@ -1,172 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Action for displaying an OAuth verifier pin
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Action
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
/**
* Class for displaying an OAuth verifier pin
*
* XXX: I'm pretty sure we don't need to check the logged in state here. -- Zach
*
* @category Action
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiOAuthPinAction extends InfoAction
{
function __construct($title, $message, $verifier, $desktopMode = false)
{
$this->verifier = $verifier;
$this->title = $title;
$this->desktopMode = $desktopMode;
parent::__construct($title, $message);
}
/**
* Show body - override to add a special CSS class for the pin pages's
* "desktop mode" (minimal display)
*
* Calls template methods
*
* @return nothing
*/
function showBody()
{
$bodyClasses = array();
if ($this->desktopMode) {
$bodyClasses[] = 'oauth-desktop-mode';
}
if (common_current_user()) {
$bodyClasses[] = 'user_in';
}
$attrs = array('id' => strtolower($this->trimmed('action')));
if (!empty($bodyClasses)) {
$attrs['class'] = implode(' ', $bodyClasses);
}
$this->elementStart('body', $attrs);
$this->elementStart('div', array('id' => 'wrap'));
if (Event::handle('StartShowHeader', array($this))) {
$this->showHeader();
Event::handle('EndShowHeader', array($this));
}
$this->showCore();
if (Event::handle('StartShowFooter', array($this))) {
$this->showFooter();
Event::handle('EndShowFooter', array($this));
}
$this->elementEnd('div');
$this->showScripts();
$this->elementEnd('body');
}
/**
* A local menu
*
* Shows different login/register actions.
*
* @return void
*/
function showLocalNav()
{
// NOP
}
/*
* Override - suppress output in "desktop" mode
*/
function showHeader()
{
if ($this->desktopMode == false) {
parent::showHeader();
}
}
/*
* Override - suppress output in "desktop" mode
*/
function showAside()
{
if ($this->desktopMode == false) {
parent::showAside();
}
}
/*
* Override - suppress output in "desktop" mode
*/
function showFooter()
{
if ($this->desktopMode == false) {
parent::showFooter();
}
}
/**
* Show site notice.
*
* @return nothing
*/
function showSiteNotice()
{
// NOP
}
/**
* Show notice form.
*
* Show the form for posting a new notice
*
* @return nothing
*/
function showNoticeForm()
{
// NOP
}
/**
* Display content.
*
* @return nothing
*/
function showContent()
{
$this->element('div', array('class' => 'info'), $this->message);
$this->element('div', array('id' => 'oauth_pin'), $this->verifier);
}
}

View File

@@ -1,152 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Issue temporary OAuth credentials (a request token)
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @copyright 2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Issue temporary OAuth credentials (a request token)
*
* @category API
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiOAuthRequestTokenAction extends ApiOAuthAction
{
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
function prepare(array $args = array())
{
parent::prepare($args);
// XXX: support "force_login" parameter like Twitter? (Forces the user to enter
// their credentials to ensure the correct users account is authorized.)
return true;
}
/**
* Handle a request for temporary OAuth credentials
*
* Make sure the request is kosher, then emit a set of temporary
* credentials -- AKA an unauthorized request token.
*
* @param array $args array of arguments
*
* @return void
*/
function handle()
{
parent::handle();
$datastore = new ApiGNUsocialOAuthDataStore();
$server = new OAuthServer($datastore);
$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
$server->add_signature_method($hmac_method);
try {
$req = OAuthRequest::from_request();
// verify callback
if (!$this->verifyCallback($req->get_parameter('oauth_callback'))) {
throw new OAuthException(
"You must provide a valid URL or 'oob' in oauth_callback.",
400
);
}
// check signature and issue a new request token
$token = $server->fetch_request_token($req);
common_log(
LOG_INFO,
sprintf(
"API OAuth - Issued request token %s for consumer %s with oauth_callback %s",
$token->key,
$req->get_parameter('oauth_consumer_key'),
"'" . $req->get_parameter('oauth_callback') ."'"
)
);
// return token to the client
$this->showRequestToken($token);
} catch (OAuthException $e) {
common_log(LOG_WARNING, 'API OAuthException - ' . $e->getMessage());
// Return 401 for for bad credentials or signature problems,
// and 400 for missing or unsupported parameters
$code = $e->getCode();
$this->clientError($e->getMessage(), empty($code) ? 401 : $code, 'text');
}
}
/*
* Display temporary OAuth credentials
*/
function showRequestToken($token)
{
header('Content-Type: application/x-www-form-urlencoded');
print $token;
print '&oauth_callback_confirmed=true';
}
/* Make sure the callback parameter contains either a real URL
* or the string 'oob'.
*
* @todo Check for evil/banned URLs here
*
* @return boolean true or false
*/
function verifyCallback($callback)
{
if ($callback == "oob") {
common_debug("OAuth request token requested for out of band client.");
// XXX: Should we throw an error if a client is registered as a
// web application but requests the pin based workflow? For now I'm
// allowing the workflow to proceed and issuing a pin. --Zach
return true;
} else {
return filter_var($callback, FILTER_VALIDATE_URL);
}
}
}

View File

@@ -1,392 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Action for showing Twitter-like Atom search results
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Search
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @copyright 2008-2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
/**
* Action for outputting search results in Twitter compatible Atom
* format.
*
* TODO: abstract Atom stuff into a ruseable base class like
* RSS10Action.
*
* @category Search
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*
* @see ApiPrivateAuthAction
*/
class ApiSearchAtomAction extends ApiPrivateAuthAction
{
var $cnt;
var $query;
var $lang;
var $rpp;
var $page;
var $since_id;
var $geocode;
/**
* Constructor
*
* Just wraps the Action constructor.
*
* @param string $output URI to output to, default = stdout
* @param boolean $indent Whether to indent output, default true
*
* @see Action::__construct
*/
function __construct($output='php://output', $indent=null)
{
parent::__construct($output, $indent);
}
/**
* Do we need to write to the database?
*
* @return boolean true
*/
function isReadonly()
{
return true;
}
/**
* Read arguments and initialize members
*
* @param array $args Arguments from $_REQUEST
*
* @return boolean success
*/
function prepare(array $args = array())
{
parent::prepare($args);
$this->query = $this->trimmed('q');
$this->lang = $this->trimmed('lang');
$this->rpp = $this->trimmed('rpp');
if (!$this->rpp) {
$this->rpp = 15;
}
if ($this->rpp > 100) {
$this->rpp = 100;
}
$this->page = $this->trimmed('page');
if (!$this->page) {
$this->page = 1;
}
// TODO: Suppport max_id -- we need to tweak the backend
// Search classes to support it.
$this->since_id = $this->trimmed('since_id');
$this->geocode = $this->trimmed('geocode');
// TODO: Also, language and geocode
return true;
}
/**
* Handle a request
*
* @param array $args Arguments from $_REQUEST
*
* @return void
*/
function handle()
{
parent::handle();
common_debug("In apisearchatom handle()");
$this->showAtom();
}
/**
* Get the notices to output as results. This also sets some class
* attrs so we can use them to calculate pagination, and output
* since_id and max_id.
*
* @return array an array of Notice objects sorted in reverse chron
*/
function getNotices()
{
// TODO: Support search operators like from: and to:, boolean, etc.
$notices = array();
$notice = new Notice();
// lcase it for comparison
$q = strtolower($this->query);
$search_engine = $notice->getSearchEngine('notice');
$search_engine->set_sort_mode('chron');
$search_engine->limit(($this->page - 1) * $this->rpp,
$this->rpp + 1, true);
if (false === $search_engine->query($q)) {
$this->cnt = 0;
} else {
$this->cnt = $notice->find();
}
$cnt = 0;
$this->max_id = 0;
if ($this->cnt > 0) {
while ($notice->fetch()) {
++$cnt;
if (!$this->max_id) {
$this->max_id = $notice->id;
}
if ($this->since_id && $notice->id <= $this->since_id) {
break;
}
if ($cnt > $this->rpp) {
break;
}
$notices[] = clone($notice);
}
}
return $notices;
}
/**
* Output search results as an Atom feed
*
* @return void
*/
function showAtom()
{
$notices = $this->getNotices();
$this->initAtom();
$this->showFeed();
foreach ($notices as $n) {
$profile = $n->getProfile();
// Don't show notices from deleted users
if (!empty($profile)) {
$this->showEntry($n);
}
}
$this->endAtom();
}
/**
* Show feed specific Atom elements
*
* @return void
*/
function showFeed()
{
// TODO: A9 OpenSearch stuff like search.twitter.com?
$server = common_config('site', 'server');
$sitename = common_config('site', 'name');
// XXX: Use xmlns:statusnet instead?
$this->elementStart('feed',
array('xmlns' => 'http://www.w3.org/2005/Atom',
// XXX: xmlns:twitter causes Atom validation to fail
// It's used for the source attr on notices
'xmlns:twitter' => 'http://api.twitter.com/',
'xml:lang' => 'en-US')); // XXX Other locales ?
$taguribase = TagURI::base();
$this->element('id', null, "tag:$taguribase:search/$server");
$site_uri = common_path(false);
$search_uri = $site_uri . 'api/search.atom?q=' . urlencode($this->query);
if ($this->rpp != 15) {
$search_uri .= '&rpp=' . $this->rpp;
}
// FIXME: this alternate link is not quite right because our
// web-based notice search doesn't support a rpp (responses per
// page) param yet
$this->element('link', array('type' => 'text/html',
'rel' => 'alternate',
'href' => $site_uri . 'search/notice?q=' .
urlencode($this->query)));
// self link
$self_uri = $search_uri;
$self_uri .= ($this->page > 1) ? '&page=' . $this->page : '';
$this->element('link', array('type' => 'application/atom+xml',
'rel' => 'self',
'href' => $self_uri));
// @todo Needs i18n?
$this->element('title', null, "$this->query - $sitename Search");
$this->element('updated', null, common_date_iso8601('now'));
// XXX: The below "rel" links are not valid Atom, but it's what
// Twitter does...
// refresh link
$refresh_uri = $search_uri . "&since_id=" . $this->max_id;
$this->element('link', array('type' => 'application/atom+xml',
'rel' => 'refresh',
'href' => $refresh_uri));
// pagination links
if ($this->cnt > $this->rpp) {
$next_uri = $search_uri . "&max_id=" . $this->max_id .
'&page=' . ($this->page + 1);
$this->element('link', array('type' => 'application/atom+xml',
'rel' => 'next',
'href' => $next_uri));
}
if ($this->page > 1) {
$previous_uri = $search_uri . "&max_id=" . $this->max_id .
'&page=' . ($this->page - 1);
$this->element('link', array('type' => 'application/atom+xml',
'rel' => 'previous',
'href' => $previous_uri));
}
}
/**
* Build an Atom entry similar to search.twitter.com's based on
* a given notice
*
* @param Notice $notice the notice to use
*
* @return void
*/
function showEntry($notice)
{
$server = common_config('site', 'server');
$profile = $notice->getProfile();
$nurl = common_local_url('shownotice', array('notice' => $notice->id));
$this->elementStart('entry');
$taguribase = TagURI::base();
$this->element('id', null, "tag:$taguribase:$notice->id");
$this->element('published', null, common_date_w3dtf($notice->created));
$this->element('link', array('type' => 'text/html',
'rel' => 'alternate',
'href' => $nurl));
$this->element('title', null, common_xml_safe_str(trim($notice->content)));
$this->element('content', array('type' => 'html'), $notice->getRendered());
$this->element('updated', null, common_date_w3dtf($notice->created));
$this->element('link', array('type' => 'image/png',
// XXX: Twitter uses rel="image" (not valid)
'rel' => 'related',
'href' => $profile->avatarUrl()));
// @todo: Here is where we'd put in a link to an atom feed for threads
$source = null;
$source_link = null;
$ns = $notice->getSource();
if ($ns instanceof Notice_source) {
$source = $ns->code;
if (!empty($ns->url)) {
$source_link = $ns->url;
if (!empty($ns->name)) {
$source = $ns->name;
}
}
}
$this->element("twitter:source", null, $source);
$this->element("twitter:source_link", null, $source_link);
$this->elementStart('author');
$name = $profile->nickname;
if ($profile->fullname) {
// @todo Needs proper i18n?
$name .= ' (' . $profile->fullname . ')';
}
$this->element('name', null, $name);
$this->element('uri', null, common_profile_uri($profile));
$this->elementEnd('author');
$this->elementEnd('entry');
}
/**
* Initialize the Atom output, send headers
*
* @return void
*/
function initAtom()
{
header('Content-Type: application/atom+xml; charset=utf-8');
$this->startXml();
}
/**
* End the Atom feed
*
* @return void
*/
function endAtom()
{
$this->elementEnd('feed');
}
}

View File

@@ -1,136 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Action for showing Twitter-like JSON search results
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Search
* @package GNUsocial
* @author Zach Copley <zach@status.net>
* @copyright 2008-2010 StatusNet, Inc.
* @copyright 2013 Free Software Foundation, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Action handler for Twitter-compatible API search
*
* @category Search
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
* @see ApiAction
*/
class ApiSearchJSONAction extends ApiPrivateAuthAction
{
var $query;
var $lang;
var $rpp;
var $page;
var $since_id;
var $limit;
var $geocode;
/**
* Initialization.
*
* @param array $args Web and URL arguments
*
* @return boolean true if nothing goes wrong
*/
function prepare(array $args = array())
{
parent::prepare($args);
$this->query = $this->trimmed('q');
$this->lang = $this->trimmed('lang');
$this->rpp = $this->trimmed('rpp');
if (!$this->rpp) {
$this->rpp = 15;
}
if ($this->rpp > 100) {
$this->rpp = 100;
}
$this->page = $this->trimmed('page');
if (!$this->page) {
$this->page = 1;
}
// TODO: Suppport max_id -- we need to tweak the backend
// Search classes to support it.
$this->since_id = $this->trimmed('since_id');
$this->geocode = $this->trimmed('geocode');
return true;
}
/**
* Handle a request
*
* @param array $args Arguments from $_REQUEST
*
* @return void
*/
function handle()
{
parent::handle();
$this->showResults();
}
/**
* Show search results
*
* @return void
*/
function showResults()
{
// TODO: Support search operators like from: and to:, boolean, etc.
$notice = new Notice();
$this->notices = array();
$search_engine = $notice->getSearchEngine('notice');
$search_engine->set_sort_mode('chron');
$search_engine->limit(($this->page - 1) * $this->rpp, $this->rpp + 1);
if ($search_engine->query($this->query)) {
$cnt = $notice->find();
$this->notices = $notice->fetchAll();
}
$this->showJsonTimeline($this->notices);
}
/**
* Do we need to write to the database?
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
}

View File

@@ -1,113 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Destroy a notice through the API
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Tom Blankenship <mac65@mac65.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Deletes one of the authenticating user's statuses (notices).
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Tom Blankenship <mac65@mac65.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiStatusesDestroyAction extends ApiAuthAction
{
protected function prepare(array $args=array())
{
parent::prepare($args);
if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
// TRANS: Client error displayed trying to delete a status not using POST or DELETE.
// TRANS: POST and DELETE should not be translated.
throw new ClientException(_('This method requires a POST or DELETE.'));
}
// FIXME: Return with a Not Acceptable status code?
if (!in_array($this->format, array('xml', 'json'))) {
// TRANS: Client error displayed when coming across a non-supported API method.
throw new ClientException(_('API method not found.'), 404);
}
try {
$this->notice = Notice::getByID($this->trimmed('id'));
} catch (NoResultException $e) {
// TRANS: Client error displayed trying to delete a status with an invalid ID.
throw new ClientException(_('No status found with that ID.'), 404);
}
return true;
}
protected function handle()
{
parent::handle();
if (!$this->scoped->sameAs($this->notice->getProfile()) && !$this->scoped->hasRight(Right::DELETEOTHERSNOTICE)) {
// TRANS: Client error displayed trying to delete a status of another user.
throw new AuthorizationException(_('You may not delete another user\'s status.'));
}
if (Event::handle('StartDeleteOwnNotice', array($this->scoped->getUser(), $this->notice))) {
$this->notice->deleteAs($this->scoped);
Event::handle('EndDeleteOwnNotice', array($this->scoped->getUser(), $this->notice));
}
$this->showNotice();
}
/**
* Show the deleted notice
*
* @return void
*/
function showNotice()
{
if (!empty($this->notice)) {
if ($this->format == 'xml') {
$this->showSingleXmlStatus($this->notice);
} elseif ($this->format == 'json') {
$this->show_single_json_status($this->notice);
}
}
}
}

View File

@@ -1,224 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show a notice (as a Twitter-style status)
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Tom Blankenship <mac65@mac65.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Returns the notice specified by id as a Twitter-style status and inline user
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Tom Blankenship <mac65@mac65.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiStatusesShowAction extends ApiPrivateAuthAction
{
var $notice_id = null;
var $notice = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
// 'id' is an undocumented parameter in Twitter's API. Several
// clients make use of it, so we support it too.
// show.json?id=12345 takes precedence over /show/12345.json
$this->notice_id = (int)$this->trimmed('id');
$this->notice = null;
try {
$this->notice = Notice::getByID($this->notice_id);
} catch (NoResultException $e) {
// No such notice was found, maybe it was deleted?
$deleted = null;
Event::handle('IsNoticeDeleted', array($this->notice_id, &$deleted));
if ($deleted === true) {
// TRANS: Client error displayed trying to show a deleted notice.
throw new ClientException(_('Notice deleted.'), 410);
}
// TRANS: Client error displayed trying to show a non-existing notice.
throw new ClientException(_('No such notice.'), 404);
}
if (!$this->notice->inScope($this->scoped)) {
// TRANS: Client exception thrown when trying a view a notice the user has no access to.
throw new ClientException(_('Access restricted.'), 403);
}
return true;
}
/**
* Handle the request
*
* Check the format and show the notice
*
* @return void
*/
protected function handle()
{
parent::handle();
if (!in_array($this->format, array('xml', 'json', 'atom'))) {
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
switch ($_SERVER['REQUEST_METHOD']) {
case 'GET':
$this->showNotice();
break;
case 'DELETE':
$this->deleteNotice();
break;
default:
// TRANS: Client error displayed calling an unsupported HTTP error in API status show.
$this->clientError(_('HTTP method not supported.'), 405);
}
}
/**
* Show the notice
*
* @return void
*/
function showNotice()
{
switch ($this->format) {
case 'xml':
$this->showSingleXmlStatus($this->notice);
break;
case 'json':
$this->show_single_json_status($this->notice);
break;
case 'atom':
$this->showSingleAtomStatus($this->notice);
break;
default:
// TRANS: Exception thrown requesting an unsupported notice output format.
// TRANS: %s is the requested output format.
throw new Exception(sprintf(_("Unsupported format: %s."), $this->format));
}
}
/**
* We expose AtomPub here, so non-GET/HEAD reqs must be read/write.
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD');
}
/**
* When was this notice last modified?
*
* @return string datestamp of the latest notice in the stream
*/
function lastModified()
{
return strtotime($this->notice->created);
}
/**
* An entity tag for this notice
*
* Returns an Etag based on the action name, language, and
* timestamps of the notice
*
* @return string etag
*/
function etag()
{
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
$this->notice->id,
strtotime($this->notice->created))
)
. '"';
}
function deleteNotice()
{
if ($this->format != 'atom') {
// TRANS: Client error displayed when trying to delete a notice not using the Atom format.
$this->clientError(_('Can only delete using the Atom format.'));
}
if (empty($this->auth_user) ||
($this->notice->profile_id != $this->auth_user->id &&
!$this->auth_user->hasRight(Right::DELETEOTHERSNOTICE))) {
// TRANS: Client error displayed when a user has no rights to delete notices of other users.
$this->clientError(_('Cannot delete this notice.'), 403);
}
if (Event::handle('StartDeleteOwnNotice', array($this->auth_user, $this->notice))) {
$this->notice->deleteAs($this->scoped);
Event::handle('EndDeleteOwnNotice', array($this->auth_user, $this->notice));
}
// @fixme is there better output we could do here?
header('HTTP/1.1 200 OK');
header('Content-Type: text/plain');
// TRANS: Confirmation of notice deletion in API. %d is the ID (number) of the deleted notice.
print(sprintf(_('Deleted notice %d'), $this->notice->id));
print("\n");
}
}

View File

@@ -1,368 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Post a notice (update your status) through the API
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Tom Blankenship <mac65@mac65.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @copyright 2009-2010 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
/* External API usage documentation. Please update when you change how this method works. */
/*! @page statusesupdate statuses/update
@section Description
Updates the authenticating user's status. Requires the status parameter specified below.
Request must be a POST.
@par URL pattern
/api/statuses/update.:format
@par Formats (:format)
xml, json, atom
@par HTTP Method(s)
POST
@par Requires Authentication
Yes
@param status (Required) The URL-encoded text of the status update.
@param source (Optional) The source application name, if using HTTP authentication or an anonymous OAuth consumer.
@param in_reply_to_status_id (Optional) The ID of an existing status that the update is in reply to.
@param lat (Optional) The latitude the status refers to.
@param long (Optional) The longitude the status refers to.
@param media (Optional) a media upload, such as an image or movie file.
@sa @ref authentication
@sa @ref apiroot
@subsection usagenotes Usage notes
@li The URL pattern is relative to the @ref apiroot.
@li If the @e source parameter is not supplied the source of the status will default to 'api'. When authenticated via a registered OAuth application, the application's registered name and URL will always override the source parameter.
@li The XML response uses <a href="http://georss.org/Main_Page">GeoRSS</a>
to encode the latitude and longitude (see example response below <georss:point>).
@li Data uploaded via the @e media parameter should be multipart/form-data encoded.
@subsection exampleusage Example usage
@verbatim
curl -u username:password http://example.com/api/statuses/update.xml -d status='Howdy!' -d lat='30.468' -d long='-94.743'
@endverbatim
@subsection exampleresponse Example response
@verbatim
<?xml version="1.0" encoding="UTF-8"?>
<status>
<text>Howdy!</text>
<truncated>false</truncated>
<created_at>Tue Mar 30 23:28:05 +0000 2010</created_at>
<in_reply_to_status_id/>
<source>api</source>
<id>26668724</id>
<in_reply_to_user_id/>
<in_reply_to_screen_name/>
<geo xmlns:georss="http://www.georss.org/georss">
<georss:point>30.468 -94.743</georss:point>
</geo>
<favorited>false</favorited>
<user>
<id>25803</id>
<name>Jed Sanders</name>
<screen_name>jedsanders</screen_name>
<location>Hoop and Holler, Texas</location>
<description>I like to think of myself as America's Favorite.</description>
<profile_image_url>http://avatar.example.com/25803-48-20080924200604.png</profile_image_url>
<url>http://jedsanders.net</url>
<protected>false</protected>
<followers_count>5</followers_count>
<profile_background_color/>
<profile_text_color/>
<profile_link_color/>
<profile_sidebar_fill_color/>
<profile_sidebar_border_color/>
<friends_count>2</friends_count>
<created_at>Wed Sep 24 20:04:00 +0000 2008</created_at>
<favourites_count>0</favourites_count>
<utc_offset>0</utc_offset>
<time_zone>UTC</time_zone>
<profile_background_image_url/>
<profile_background_tile>false</profile_background_tile>
<statuses_count>70</statuses_count>
<following>true</following>
<notifications>true</notifications>
</user>
</status>
@endverbatim
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Updates the authenticating user's status (posts a notice).
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Tom Blankenship <mac65@mac65.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiStatusesUpdateAction extends ApiAuthAction
{
protected $needPost = true;
var $status = null;
var $in_reply_to_status_id = null;
var $lat = null;
var $lon = null;
var $media_ids = array(); // file_id in the keys
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->status = $this->trimmed('status');
$this->lat = $this->trimmed('lat');
$this->lon = $this->trimmed('long');
$matches = array();
common_debug(get_called_class().': media_ids=='._ve($this->trimmed('media_ids')));
if (preg_match_all('/\d+/', $this->trimmed('media_ids'), $matches) !== false) {
foreach (array_unique($matches[0]) as $match) {
try {
$this->media_ids[$match] = File::getByID($match);
} catch (EmptyPkeyValueException $e) {
// got a zero from the client, at least Twidere does this on occasion
} catch (NoResultException $e) {
// File ID was not found. Do we abort and report to the client?
}
}
}
$this->in_reply_to_status_id
= intval($this->trimmed('in_reply_to_status_id'));
return true;
}
/**
* Handle the request
*
* Make a new notice for the update, save it, and show it
*
* @return void
*/
protected function handle()
{
parent::handle();
// Workaround for PHP returning empty $_POST and $_FILES when POST
// length > post_max_size in php.ini
if (empty($_FILES)
&& empty($_POST)
&& ($_SERVER['CONTENT_LENGTH'] > 0)
) {
// TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit.
// TRANS: %s is the number of bytes of the CONTENT_LENGTH.
$msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.',
'The server was unable to handle that much POST data (%s bytes) due to its current configuration.',
intval($_SERVER['CONTENT_LENGTH']));
$this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
}
if (empty($this->status)) {
// TRANS: Client error displayed when the parameter "status" is missing.
$this->clientError(_('Client must provide a \'status\' parameter with a value.'));
}
if (is_null($this->scoped)) {
// TRANS: Client error displayed when updating a status for a non-existing user.
$this->clientError(_('No such user.'), 404);
}
/* Do not call shortenLinks until the whole notice has been build */
// Check for commands
$inter = new CommandInterpreter();
$cmd = $inter->handle_command($this->auth_user, $this->status);
if ($cmd) {
if ($this->supported($cmd)) {
$cmd->execute(new Channel());
}
// Cmd not supported? Twitter just returns your latest status.
// And, it returns your last status whether the cmd was successful
// or not!
$this->notice = $this->auth_user->getCurrentNotice();
} else {
$reply_to = null;
if (!empty($this->in_reply_to_status_id)) {
// Check whether notice actually exists
$reply = Notice::getKV($this->in_reply_to_status_id);
if ($reply) {
$reply_to = $this->in_reply_to_status_id;
} else {
// TRANS: Client error displayed when replying to a non-existing notice.
$this->clientError(_('Parent notice not found.'), 404);
}
}
foreach(array_keys($this->media_ids) as $media_id) {
// FIXME: Validation on this... Worst case is that if someone sends bad media_ids then
// we'll fill the notice with non-working links, so no real harm, done, but let's fix.
// The File objects are in the array, so we could get URLs from them directly.
$this->status .= ' ' . common_local_url('attachment', array('attachment' => $media_id));
}
$upload = null;
try {
$upload = MediaFile::fromUpload('media', $this->scoped);
$this->status .= ' ' . $upload->shortUrl();
/* Do not call shortenLinks until the whole notice has been build */
} catch (NoUploadedMediaException $e) {
// There was no uploaded media for us today.
}
/* Do call shortenlinks here & check notice length since notice is about to be saved & sent */
$status_shortened = $this->auth_user->shortenLinks($this->status);
if (Notice::contentTooLong($status_shortened)) {
if ($upload instanceof MediaFile) {
$upload->delete();
}
// TRANS: Client error displayed exceeding the maximum notice length.
// TRANS: %d is the maximum lenth for a notice.
$msg = _m('Maximum notice size is %d character, including attachment URL.',
'Maximum notice size is %d characters, including attachment URL.',
Notice::maxContent());
/* Use HTTP 413 error code (Request Entity Too Large)
* instead of basic 400 for better understanding
*/
$this->clientError(sprintf($msg, Notice::maxContent()), 413);
}
$content = html_entity_decode($status_shortened, ENT_NOQUOTES, 'UTF-8');
$options = array('reply_to' => $reply_to);
if ($this->scoped->shareLocation()) {
$locOptions = Notice::locationOptions($this->lat,
$this->lon,
null,
null,
$this->scoped);
$options = array_merge($options, $locOptions);
}
try {
$this->notice = Notice::saveNew(
$this->scoped->id,
$content,
$this->source,
$options
);
} catch (Exception $e) {
$this->clientError($e->getMessage(), $e->getCode());
}
if (isset($upload)) {
$upload->attachToNotice($this->notice);
}
}
$this->showNotice();
}
/**
* Show the resulting notice
*
* @return void
*/
function showNotice()
{
if (!empty($this->notice)) {
if ($this->format == 'xml') {
$this->showSingleXmlStatus($this->notice);
} elseif ($this->format == 'json') {
$this->show_single_json_status($this->notice);
} elseif ($this->format == 'atom') {
$this->showSingleAtomStatus($this->notice);
}
}
}
/**
* Is this command supported when doing an update from the API?
*
* @param string $cmd the command to check for
*
* @return boolean true or false
*/
function supported($cmd)
{
static $cmdlist = array('SubCommand', 'UnsubCommand',
'OnCommand', 'OffCommand', 'JoinCommand', 'LeaveCommand');
$supported = null;
if (Event::handle('CommandSupportedAPI', array($cmd, &$supported))) {
$supported = $supported || in_array(get_class($cmd), $cmdlist);
}
return $supported;
}
}

View File

@@ -1,254 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Base class for showing subscription information in the API
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* This class outputs a list of profiles as Twitter-style user and status objects.
* It is used by the API methods /api/statuses/(friends|followers). To support the
* social graph methods it also can output a simple list of IDs.
*
* @category API
* @package StatusNet
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
abstract class ApiSubscriptionsAction extends ApiBareAuthAction
{
var $profiles = null;
var $tag = null;
var $lite = null;
var $ids_only = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->tag = $this->arg('tag');
// Note: Twitter no longer supports 'lite'
$this->lite = $this->arg('lite');
$this->ids_only = $this->arg('ids_only');
// If called as a social graph method, show 5000 per page, otherwise 100
$this->count = isset($this->ids_only) ?
5000 : (int)$this->arg('count', 100);
$this->target = $this->getTargetProfile($this->arg('id'));
if (!($this->target instanceof Profile)) {
// TRANS: Client error displayed when requesting a list of followers for a non-existing user.
$this->clientError(_('No such user.'), 404);
}
$this->profiles = $this->getProfiles();
return true;
}
/**
* Handle the request
*
* Show the profiles
*
* @return void
*/
protected function handle()
{
parent::handle();
if (!in_array($this->format, array('xml', 'json'))) {
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
$this->initDocument($this->format);
if (isset($this->ids_only)) {
$this->showIds();
} else {
$this->showProfiles(isset($this->lite) ? false : true);
}
$this->endDocument($this->format);
}
/**
* Get profiles related to the type of subscriber/subscription action
*
* @return array Profiles
*/
abstract protected function getProfiles();
/**
* Is this action read only?
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* When was this feed last modified?
*
* @return string datestamp of the latest profile in the stream
*/
function lastModified()
{
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
return strtotime($this->profiles[0]->created);
}
return null;
}
/**
* An entity tag for this action
*
* Returns an Etag based on the action name, language, user ID, and
* timestamps of the first and last profiles in the subscriptions list
* There's also an indicator to show whether this action is being called
* as /api/statuses/(friends|followers) or /api/(friends|followers)/ids
*
* @return string etag
*/
function etag()
{
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
$last = count($this->profiles) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
$this->target->id,
// Caching tags.
isset($this->ids_only) ? 'IDs' : 'Profiles',
strtotime($this->profiles[0]->created),
strtotime($this->profiles[$last]->created))
)
. '"';
}
return null;
}
/**
* Show the profiles as Twitter-style useres and statuses
*
* @param boolean $include_statuses Whether to include the latest status
* with each user. Default true.
*
* @return void
*/
function showProfiles($include_statuses = true)
{
switch ($this->format) {
case 'xml':
$this->elementStart('users', array('type' => 'array',
'xmlns:statusnet' => 'http://status.net/schema/api/1/'));
foreach ($this->profiles as $profile) {
$this->showProfile(
$profile,
$this->format,
null,
$include_statuses
);
}
$this->elementEnd('users');
break;
case 'json':
$arrays = array();
foreach ($this->profiles as $profile) {
$arrays[] = $this->twitterUserArray(
$profile,
$include_statuses
);
}
print json_encode($arrays);
break;
default:
// TRANS: Client error displayed when requesting profiles of followers in an unsupported format.
$this->clientError(_('Unsupported format.'));
break;
}
}
/**
* Show the IDs of the profiles only. 5000 per page. To support
* the 'social graph' methods: /api/(friends|followers)/ids
*
* @return void
*/
function showIds()
{
switch ($this->format) {
case 'xml':
$this->elementStart('ids');
foreach ($this->profiles as $profile) {
$this->element('id', null, $profile->id);
}
$this->elementEnd('ids');
break;
case 'json':
$ids = array();
foreach ($this->profiles as $profile) {
$ids[] = (int)$profile->id;
}
print json_encode($ids);
break;
default:
// TRANS: Client error displayed when requesting IDs of followers in an unsupported format.
$this->clientError(_('Unsupported format.'));
break;
}
}
}

View File

@@ -1,344 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show the friends timeline
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author mac65 <mac65@mac65.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @copyright 2009-2010 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
/* External API usage documentation. Please update when you change how this method works. */
/*! @page friendstimeline statuses/friends_timeline
@section Description
Returns the 20 most recent statuses posted by the authenticating
user and that user's friends. This is the equivalent of "You and
friends" page in the web interface.
@par URL patterns
@li /api/statuses/friends_timeline.:format
@li /api/statuses/friends_timeline/:id.:format
@par Formats (:format)
xml, json, rss, atom
@par ID (:id)
username, user id
@par HTTP Method(s)
GET
@par Requires Authentication
Sometimes (see: @ref authentication)
@param user_id (Optional) Specifies a user by ID
@param screen_name (Optional) Specifies a user by screename (nickname)
@param since_id (Optional) Returns only statuses with an ID greater
than (that is, more recent than) the specified ID.
@param max_id (Optional) Returns only statuses with an ID less than
(that is, older than) or equal to the specified ID.
@param count (Optional) Specifies the number of statuses to retrieve.
@param page (Optional) Specifies the page of results to retrieve.
@sa @ref authentication
@sa @ref apiroot
@subsection usagenotes Usage notes
@li The URL pattern is relative to the @ref apiroot.
@li The XML response uses <a href="http://georss.org/Main_Page">GeoRSS</a>
to encode the latitude and longitude (see example response below <georss:point>).
@subsection exampleusage Example usage
@verbatim
curl http://identi.ca/api/statuses/friends_timeline/evan.xml?count=1&page=2
@endverbatim
@subsection exampleresponse Example response
@verbatim
<?xml version="1.0"?>
<statuses type="array">
<status>
<text>back from the !yul !drupal meet with Evolving Web folk, @anarcat, @webchick and others, and an interesting refresher on SQL indexing</text>
<truncated>false</truncated>
<created_at>Wed Mar 31 01:33:02 +0000 2010</created_at>
<in_reply_to_status_id/>
<source>&lt;a href="http://somesourcecode.net/microblog/"&gt;mbpidgin&lt;/a&gt;</source>
<id>26674201</id>
<in_reply_to_user_id/>
<in_reply_to_screen_name/>
<geo/>
<favorited>false</favorited>
<user>
<id>246</id>
<name>Mark</name>
<screen_name>lambic</screen_name>
<location>Montreal, Canada</location>
<description>Geek</description>
<profile_image_url>http://avatar.identi.ca/246-48-20080702141545.png</profile_image_url>
<url>http://lambic.co.uk</url>
<protected>false</protected>
<followers_count>73</followers_count>
<profile_background_color>#F0F2F5</profile_background_color>
<profile_text_color/>
<profile_link_color>#002E6E</profile_link_color>
<profile_sidebar_fill_color>#CEE1E9</profile_sidebar_fill_color>
<profile_sidebar_border_color/>
<friends_count>58</friends_count>
<created_at>Wed Jul 02 14:12:15 +0000 2008</created_at>
<favourites_count>2</favourites_count>
<utc_offset>-14400</utc_offset>
<time_zone>US/Eastern</time_zone>
<profile_background_image_url/>
<profile_background_tile>false</profile_background_tile>
<statuses_count>933</statuses_count>
<following>false</following>
<notifications>false</notifications>
</user>
</status>
</statuses>
@endverbatim
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Returns the most recent notices (default 20) posted by the target user.
* This is the equivalent of 'You and friends' page accessed via Web.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author mac65 <mac65@mac65.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiTimelineFriendsAction extends ApiBareAuthAction
{
var $notices = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->target = $this->getTargetProfile($this->arg('id'));
if (!($this->target instanceof Profile)) {
// TRANS: Client error displayed when requesting dents of a user and friends for a user that does not exist.
$this->clientError(_('No such user.'), 404);
}
$this->notices = $this->getNotices();
return true;
}
/**
* Handle the request
*
* Just show the notices
*
* @return void
*/
protected function handle()
{
parent::handle();
$this->showTimeline();
}
/**
* Show the timeline of notices
*
* @return void
*/
function showTimeline()
{
$sitename = common_config('site', 'name');
// TRANS: Title of API timeline for a user and friends.
// TRANS: %s is a username.
$title = sprintf(_("%s and friends"), $this->target->nickname);
$taguribase = TagURI::base();
$id = "tag:$taguribase:FriendsTimeline:" . $this->target->id;
$subtitle = sprintf(
// TRANS: Message is used as a subtitle. %1$s is a user nickname, %2$s is a site name.
_('Updates from %1$s and friends on %2$s!'),
$this->target->nickname,
$sitename
);
$logo = $this->target->avatarUrl(AVATAR_PROFILE_SIZE);
$link = common_local_url('all',
array('nickname' => $this->target->nickname));
$self = $this->getSelfUri();
switch($this->format) {
case 'xml':
$this->showXmlTimeline($this->notices);
break;
case 'rss':
$this->showRssTimeline(
$this->notices,
$title,
$link,
$subtitle,
null,
$logo,
$self
);
break;
case 'atom':
header('Content-Type: application/atom+xml; charset=utf-8');
$atom = new AtomNoticeFeed($this->auth_user);
$atom->setId($id);
$atom->setTitle($title);
$atom->setSubtitle($subtitle);
$atom->setLogo($logo);
$atom->setUpdated('now');
$atom->addLink($link);
$atom->setSelfLink($self);
$atom->addEntryFromNotices($this->notices);
$this->raw($atom->getString());
break;
case 'json':
$this->showJsonTimeline($this->notices);
break;
case 'as':
header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE);
$doc = new ActivityStreamJSONDocument($this->auth_user, $title);
$doc->addLink($link, 'alternate', 'text/html');
$doc->addItemsFromNotices($this->notices);
$this->raw($doc->asString());
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
/**
* Get notices
*
* @return array notices
*/
function getNotices()
{
$notices = array();
$stream = new InboxNoticeStream($this->target, $this->scoped);
$notice = $stream->getNotices(($this->page-1) * $this->count,
$this->count,
$this->since_id,
$this->max_id);
while ($notice->fetch()) {
$notices[] = clone($notice);
}
return $notices;
}
/**
* Is this action read only?
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* When was this feed last modified?
*
* @return string datestamp of the latest notice in the stream
*/
function lastModified()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
return strtotime($this->notices[0]->created);
}
return null;
}
/**
* An entity tag for this stream
*
* Returns an Etag based on the action name, language, user ID, and
* timestamps of the first and last notice in the timeline
*
* @return string etag
*/
function etag()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
$last = count($this->notices) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
$this->target->id,
strtotime($this->notices[0]->created),
strtotime($this->notices[$last]->created))
)
. '"';
}
return null;
}
}

View File

@@ -1,221 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show a group's notices
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009-2010 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Returns the most recent notices (default 20) posted to the group specified by ID
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiTimelineGroupAction extends ApiPrivateAuthAction
{
var $group = null;
var $notices = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->group = $this->getTargetGroup($this->arg('id'));
return true;
}
/**
* Handle the request
*
* Just show the notices
*
* @return void
*/
protected function handle()
{
parent::handle();
if (empty($this->group)) {
// TRANS: Client error displayed requesting most recent notices to a group for a non-existing group.
$this->clientError(_('Group not found.'), 404);
}
$this->notices = $this->getNotices();
$this->showTimeline();
}
/**
* Show the timeline of notices
*
* @return void
*/
function showTimeline()
{
// We'll pull common formatting out of this for other formats
$atom = new AtomGroupNoticeFeed($this->group, $this->auth_user);
$self = $this->getSelfUri();
$link = common_local_url('showgroup',
array('nickname' => $this->group->nickname));
switch($this->format) {
case 'xml':
$this->showXmlTimeline($this->notices);
break;
case 'rss':
$this->showRssTimeline(
$this->notices,
$atom->title,
$this->group->homeUrl(),
$atom->subtitle,
null,
$atom->logo,
$self
);
break;
case 'atom':
header('Content-Type: application/atom+xml; charset=utf-8');
$atom->addEntryFromNotices($this->notices);
$this->raw($atom->getString());
break;
case 'json':
$this->showJsonTimeline($this->notices);
break;
case 'as':
header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE);
$doc = new ActivityStreamJSONDocument($this->auth_user);
$doc->setTitle($atom->title);
$doc->addLink($link, 'alternate', 'text/html');
$doc->addItemsFromNotices($this->notices);
$this->raw($doc->asString());
break;
default:
// TRANS: Client error displayed when trying to handle an unknown API method.
$this->clientError(_('API method not found.'), 404);
}
}
/**
* Get notices
*
* @return array notices
*/
function getNotices()
{
$notices = array();
$notice = $this->group->getNotices(
($this->page-1) * $this->count,
$this->count,
$this->since_id,
$this->max_id
);
while ($notice->fetch()) {
$notices[] = clone($notice);
}
return $notices;
}
/**
* Is this action read only?
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* When was this feed last modified?
*
* @return string datestamp of the latest notice in the stream
*/
function lastModified()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
return strtotime($this->notices[0]->created);
}
return null;
}
/**
* An entity tag for this stream
*
* Returns an Etag based on the action name, language, group ID and
* timestamps of the first and last notice in the timeline
*
* @return string etag
*/
function etag()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
$last = count($this->notices) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
$this->group->id,
strtotime($this->notices[0]->created),
strtotime($this->notices[$last]->created))
)
. '"';
}
return null;
}
}

View File

@@ -1,249 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show the home timeline
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author mac65 <mac65@mac65.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Returns the most recent notices (default 20) posted by the target user.
* This is the equivalent of 'You and friends' page accessed via Web.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author mac65 <mac65@mac65.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiTimelineHomeAction extends ApiBareAuthAction
{
var $notices = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->target = $this->getTargetProfile($this->arg('id'));
if (!($this->target instanceof Profile)) {
// TRANS: Client error displayed when requesting most recent dents by user and friends for a non-existing user.
$this->clientError(_('No such user.'), 404);
}
$this->notices = $this->getNotices();
return true;
}
/**
* Handle the request
*
* Just show the notices
*
* @return void
*/
protected function handle()
{
parent::handle();
$this->showTimeline();
}
/**
* Show the timeline of notices
*
* @return void
*/
function showTimeline()
{
$sitename = common_config('site', 'name');
// TRANS: Timeline title for user and friends. %s is a user nickname.
$title = sprintf(_("%s and friends"), $this->target->nickname);
$taguribase = TagURI::base();
$id = "tag:$taguribase:HomeTimeline:" . $this->target->id;
$subtitle = sprintf(
// TRANS: Message is used as a subtitle. %1$s is a user nickname, %2$s is a site name.
_('Updates from %1$s and friends on %2$s!'),
$this->target->nickname, $sitename
);
$logo = $this->target->avatarUrl(AVATAR_PROFILE_SIZE);
$link = common_local_url('all',
array('nickname' => $this->target->nickname));
$self = $this->getSelfUri();
switch($this->format) {
case 'xml':
$this->showXmlTimeline($this->notices);
break;
case 'rss':
$this->showRssTimeline(
$this->notices,
$title,
$link,
$subtitle,
null,
$logo,
$self
);
break;
case 'atom':
header('Content-Type: application/atom+xml; charset=utf-8');
$atom = new AtomNoticeFeed($this->auth_user);
$atom->setId($id);
$atom->setTitle($title);
$atom->setSubtitle($subtitle);
$atom->setLogo($logo);
$atom->setUpdated('now');
$atom->addLink($link);
$atom->setSelfLink($self);
$atom->addEntryFromNotices($this->notices);
$this->raw($atom->getString());
break;
case 'json':
$this->showJsonTimeline($this->notices);
break;
case 'as':
header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE);
$doc = new ActivityStreamJSONDocument($this->auth_user);
$doc->setTitle($title);
$doc->addLink($link, 'alternate', 'text/html');
$doc->addItemsFromNotices($this->notices);
$this->raw($doc->asString());
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
/**
* Get notices
*
* @return array notices
*/
function getNotices()
{
$notices = array();
$stream = new InboxNoticeStream($this->target, $this->scoped);
$notice = $stream->getNotices(($this->page-1) * $this->count,
$this->count,
$this->since_id,
$this->max_id);
while ($notice->fetch()) {
$notices[] = clone($notice);
}
return $notices;
}
/**
* Is this action read only?
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* When was this feed last modified?
*
* @return string datestamp of the latest notice in the stream
*/
function lastModified()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
return strtotime($this->notices[0]->created);
}
return null;
}
/**
* An entity tag for this stream
*
* Returns an Etag based on the action name, language, user ID, and
* timestamps of the first and last notice in the timeline
*
* @return string etag
*/
function etag()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
$last = count($this->notices) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
$this->target->id,
strtotime($this->notices[0]->created),
strtotime($this->notices[$last]->created))
)
. '"';
}
return null;
}
}

View File

@@ -1,248 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show a list's notices
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
require_once INSTALLDIR . '/lib/atomlistnoticefeed.php';
/**
* Returns the most recent notices (default 20) posted to the list specified by ID
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiTimelineListAction extends ApiPrivateAuthAction
{
var $list = null;
var $notices = array();
var $next_cursor = 0;
var $prev_cursor = 0;
var $cursor = -1;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->cursor = (int) $this->arg('cursor', -1);
$this->list = $this->getTargetList($this->arg('user'), $this->arg('id'));
return true;
}
/**
* Handle the request
*
* Just show the notices
*
* @return void
*/
protected function handle()
{
parent::handle();
if (empty($this->list)) {
// TRANS: Client error displayed trying to perform an action related to a non-existing list.
$this->clientError(_('List not found.'), 404);
}
$this->getNotices();
$this->showTimeline();
}
/**
* Show the timeline of notices
*
* @return void
*/
function showTimeline()
{
// We'll pull common formatting out of this for other formats
$atom = new AtomListNoticeFeed($this->list, $this->auth_user);
$self = $this->getSelfUri();
switch($this->format) {
case 'xml':
$this->initDocument('xml');
$this->elementStart('statuses_list',
array('xmlns:statusnet' => 'http://status.net/schema/api/1/'));
$this->elementStart('statuses', array('type' => 'array'));
foreach ($this->notices as $n) {
$twitter_status = $this->twitterStatusArray($n);
$this->showTwitterXmlStatus($twitter_status);
}
$this->elementEnd('statuses');
$this->element('next_cursor', null, $this->next_cursor);
$this->element('previous_cursor', null, $this->prev_cursor);
$this->elementEnd('statuses_list');
$this->endDocument('xml');
break;
case 'rss':
$this->showRssTimeline(
$this->notices,
$atom->title,
$this->list->getUri(),
$atom->subtitle,
null,
$atom->logo,
$self
);
break;
case 'atom':
header('Content-Type: application/atom+xml; charset=utf-8');
try {
$atom->setId($self);
$atom->setSelfLink($self);
$atom->addEntryFromNotices($this->notices);
$this->raw($atom->getString());
} catch (Atom10FeedException $e) {
// TRANS: Server error displayed whe trying to get a timeline fails.
// TRANS: %s is the error message.
$this->serverError(sprintf(_('Could not generate feed for list - %s'), $e->getMessage()));
}
break;
case 'json':
$this->initDocument('json');
$statuses = array();
foreach ($this->notices as $n) {
$twitter_status = $this->twitterStatusArray($n);
array_push($statuses, $twitter_status);
}
$statuses_list = array('statuses' => $statuses,
'next_cursor' => $this->next_cusror,
'next_cursor_str' => strval($this->next_cusror),
'previous_cursor' => $this->prev_cusror,
'previous_cursor_str' => strval($this->prev_cusror)
);
$this->showJsonObjects($statuses_list);
$this->initDocument('json');
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
/**
* Get notices
*
* @return array notices
*/
function getNotices()
{
$fn = array($this->list, 'getNotices');
list($this->notices, $this->next_cursor, $this->prev_cursor) =
Profile_list::getAtCursor($fn, array(), $this->cursor, 20);
if (!$this->notices) {
$this->notices = array();
}
}
/**
* Is this action read only?
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* When was this feed last modified?
*
* @return string datestamp of the latest notice in the stream
*/
function lastModified()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
return strtotime($this->notices[0]->created);
}
return null;
}
/**
* An entity tag for this stream
*
* Returns an Etag based on the action name, language, list ID and
* timestamps of the first and last notice in the timeline
*
* @return string etag
*/
function etag()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
$last = count($this->notices) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_language(),
$this->list->id,
strtotime($this->notices[0]->created),
strtotime($this->notices[$last]->created))
)
. '"';
}
return null;
}
}

View File

@@ -1,254 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show notices mentioning a user (@nickname)
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author mac65 <mac65@mac65.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Returns the most recent (default 20) mentions (status containing @nickname)
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author mac65 <mac65@mac65.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiTimelineMentionsAction extends ApiBareAuthAction
{
var $notices = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->target = $this->getTargetProfile($this->arg('id'));
if (!($this->target instanceof Profile)) {
// TRANS: Client error displayed when requesting most recent mentions for a non-existing user.
$this->clientError(_('No such user.'), 404);
}
$this->notices = $this->getNotices();
return true;
}
/**
* Handle the request
*
* Just show the notices
*
* @return void
*/
protected function handle()
{
parent::handle();
$this->showTimeline();
}
/**
* Show the timeline of notices
*
* @return void
*/
function showTimeline()
{
$sitename = common_config('site', 'name');
$title = sprintf(
// TRANS: Title for timeline of most recent mentions of a user.
// TRANS: %1$s is the StatusNet sitename, %2$s is a user nickname.
_('%1$s / Updates mentioning %2$s'),
$sitename, $this->target->nickname
);
$taguribase = TagURI::base();
$id = "tag:$taguribase:Mentions:" . $this->target->id;
$logo = $this->target->avatarUrl(AVATAR_PROFILE_SIZE);
$link = common_local_url('replies',
array('nickname' => $this->target->nickname));
$self = $this->getSelfUri();
$subtitle = sprintf(
// TRANS: Subtitle for timeline of most recent mentions of a user.
// TRANS: %1$s is the StatusNet sitename, %2$s is a user nickname,
// TRANS: %3$s is a user's full name.
_('%1$s updates that reply to updates from %3$s / %2$s.'),
$sitename, $this->target->nickname, $this->target->getBestName()
);
switch($this->format) {
case 'xml':
$this->showXmlTimeline($this->notices);
break;
case 'rss':
$this->showRssTimeline(
$this->notices,
$title,
$link,
$subtitle,
null,
$logo,
$self
);
break;
case 'atom':
header('Content-Type: application/atom+xml; charset=utf-8');
$atom = new AtomNoticeFeed($this->auth_user);
$atom->setId($id);
$atom->setTitle($title);
$atom->setSubtitle($subtitle);
$atom->setLogo($logo);
$atom->setUpdated('now');
$atom->addLink($link);
$atom->setSelfLink($self);
$atom->addEntryFromNotices($this->notices);
$this->raw($atom->getString());
break;
case 'json':
$this->showJsonTimeline($this->notices);
break;
case 'as':
header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE);
$doc = new ActivityStreamJSONDocument($this->auth_user);
$doc->setTitle($title);
$doc->addLink($link, 'alternate', 'text/html');
$doc->addItemsFromNotices($this->notices);
$this->raw($doc->asString());
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), $code = 404);
break;
}
}
/**
* Get notices
*
* @return array notices
*/
function getNotices()
{
$notices = array();
$stream = new ReplyNoticeStream($this->target->id, $this->scoped);
$notice = $stream->getNotices(($this->page - 1) * $this->count,
$this->count,
$this->since_id,
$this->max_id);
while ($notice->fetch()) {
$notices[] = clone($notice);
}
return $notices;
}
/**
* Is this action read only?
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* When was this feed last modified?
*
* @return string datestamp of the latest notice in the stream
*/
function lastModified()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
return strtotime($this->notices[0]->created);
}
return null;
}
/**
* An entity tag for this stream
*
* Returns an Etag based on the action name, language, user ID, and
* timestamps of the first and last notice in the timeline
*
* @return string etag
*/
function etag()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
$last = count($this->notices) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
$this->target->id,
strtotime($this->notices[0]->created),
strtotime($this->notices[$last]->created))
)
. '"';
}
return null;
}
}

View File

@@ -1,19 +0,0 @@
<?php
if (!defined('GNUSOCIAL')) { exit(1); }
class ApiTimelineNetworkPublicAction extends ApiTimelinePublicAction
{
function title()
{
return sprintf(_("%s network public timeline"), common_config('site', 'name'));
}
protected function getStream()
{
if (!$this->scoped instanceof Profile && common_config('public', 'localonly')) {
$this->clientError(_('Network wide public feed is not permitted without authorization'), 403);
}
return new NetworkPublicNoticeStream($this->scoped);
}
}

View File

@@ -1,335 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show the public timeline
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author mac65 <mac65@mac65.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Returns the most recent notices (default 20) posted by everybody
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author mac65 <mac65@mac65.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
/* External API usage documentation. Please update when you change how this method works. */
/*! @page publictimeline statuses/public_timeline
@section Description
Returns the 20 most recent notices from users throughout the system who have
uploaded their own avatars. Depending on configuration, it may or may not
not include notices from automatic posting services.
@par URL patterns
@li /api/statuses/public_timeline.:format
@par Formats (:format)
xml, json, rss, atom
@par HTTP Method(s)
GET
@par Requires Authentication
No
@param since_id (Optional) Returns only statuses with an ID greater
than (that is, more recent than) the specified ID.
@param max_id (Optional) Returns only statuses with an ID less than
(that is, older than) or equal to the specified ID.
@param count (Optional) Specifies the number of statuses to retrieve.
@param page (Optional) Specifies the page of results to retrieve.
@sa @ref apiroot
@subsection usagenotes Usage notes
@li The URL pattern is relative to the @ref apiroot.
@li The XML response uses <a href="http://georss.org/Main_Page">GeoRSS</a>
to encode the latitude and longitude (see example response below <georss:point>).
@subsection exampleusage Example usage
@verbatim
curl http://identi.ca/api/statuses/friends_timeline/evan.xml?count=1&page=2
@endverbatim
@subsection exampleresponse Example response
@verbatim
<?xml version="1.0" encoding="UTF-8"?>
<statuses type="array">
<status>
<text>@skwashd oh, commbank reenabled me super quick both times. but disconcerting when you don't expect it though</text>
<truncated>false</truncated>
<created_at>Sat Apr 17 00:49:12 +0000 2010</created_at>
<in_reply_to_status_id>28838393</in_reply_to_status_id>
<source>xmpp</source>
<id>28838456</id>
<in_reply_to_user_id>39303</in_reply_to_user_id>
<in_reply_to_screen_name>skwashd</in_reply_to_screen_name>
<geo></geo>
<favorited>false</favorited>
<user>
<id>44517</id>
<name>joshua may</name>
<screen_name>notjosh</screen_name>
<location></location>
<description></description>
<profile_image_url>http://avatar.identi.ca/44517-48-20090321004106.jpeg</profile_image_url>
<url></url>
<protected>false</protected>
<followers_count>17</followers_count>
<profile_background_color></profile_background_color>
<profile_text_color></profile_text_color>
<profile_link_color></profile_link_color>
<profile_sidebar_fill_color></profile_sidebar_fill_color>
<profile_sidebar_border_color></profile_sidebar_border_color>
<friends_count>20</friends_count>
<created_at>Sat Mar 21 00:40:25 +0000 2009</created_at>
<favourites_count>0</favourites_count>
<utc_offset>0</utc_offset>
<time_zone>UTC</time_zone>
<profile_background_image_url></profile_background_image_url>
<profile_background_tile>false</profile_background_tile>
<statuses_count>100</statuses_count>
<following>false</following>
<notifications>false</notifications>
</user>
</status>
[....]
</statuses>
@endverbatim
*/
class ApiTimelinePublicAction extends ApiPrivateAuthAction
{
var $notices = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->notices = $this->getNotices();
return true;
}
/**
* Handle the request
*
* Just show the notices
*
* @return void
*/
protected function handle()
{
parent::handle();
$this->showTimeline();
}
function title()
{
// TRANS: Title for site timeline. %s is the GNU social sitename.
return sprintf(_("%s public timeline"), common_config('site', 'name'));
}
/**
* Show the timeline of notices
*
* @return void
*/
function showTimeline()
{
$nonapi_action = substr($this->action, strlen('apitimeline')); // Just so we don't need to set this explicitly
$sitelogo = (common_config('site', 'logo')) ? common_config('site', 'logo') : Theme::path('logo.png');
$title = $this->title();
$taguribase = TagURI::base();
$id = "tag:$taguribase:" . ucfirst($nonapi_action) . 'Timeline'; // Public or Networkpublic probably
$link = common_local_url($nonapi_action);
$self = $this->getSelfUri();
// TRANS: Subtitle for site timeline. %s is the GNU social sitename.
$subtitle = sprintf(_("%s updates from everyone!"), common_config('site', 'name'));
switch($this->format) {
case 'xml':
$this->showXmlTimeline($this->notices);
break;
case 'rss':
$this->showRssTimeline(
$this->notices,
$title,
$link,
$subtitle,
null,
$sitelogo,
$self
);
break;
case 'atom':
header('Content-Type: application/atom+xml; charset=utf-8');
$atom = new AtomNoticeFeed($this->auth_user);
$atom->setId($id);
$atom->setTitle($title);
$atom->setSubtitle($subtitle);
$atom->setLogo($sitelogo);
$atom->setUpdated('now');
$atom->addLink(common_local_url($nonapi_action));
$atom->setSelfLink($self);
$atom->addEntryFromNotices($this->notices);
$this->raw($atom->getString());
break;
case 'json':
$this->showJsonTimeline($this->notices);
break;
case 'as':
header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE);
$doc = new ActivityStreamJSONDocument($this->auth_user);
$doc->setTitle($title);
$doc->addLink($link, 'alternate', 'text/html');
$doc->addItemsFromNotices($this->notices);
$this->raw($doc->asString());
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), $code = 404);
break;
}
}
/**
* Get notices
*
* @return array notices
*/
function getNotices()
{
$notices = array();
$stream = $this->getStream();
$notice = $stream->getNotices(($this->page - 1) * $this->count,
$this->count,
$this->since_id,
$this->max_id);
$notices = $notice->fetchAll();
NoticeList::prefill($notices);
return $notices;
}
protected function getStream()
{
return new PublicNoticeStream($this->scoped);
}
/**
* Is this action read only?
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* When was this feed last modified?
*
* @return string datestamp of the latest notice in the stream
*/
function lastModified()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
return strtotime($this->notices[0]->created);
}
return null;
}
/**
* An entity tag for this stream
*
* Returns an Etag based on the action name, language, and
* timestamps of the first and last notice in the timeline
*
* @return string etag
*/
function etag()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
$last = count($this->notices) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
strtotime($this->notices[0]->created),
strtotime($this->notices[$last]->created))
)
. '"';
}
return null;
}
}

View File

@@ -1,228 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show the latest notices for a given tag
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @copyright 2009-2010 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Returns the 20 most recent notices tagged by a given tag
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiTimelineTagAction extends ApiPrivateAuthAction
{
var $notices = null;
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->tag = $this->arg('tag');
$this->notices = $this->getNotices();
return true;
}
/**
* Handle the request
*
* Just show the notices
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
protected function handle()
{
parent::handle();
$this->showTimeline();
}
/**
* Show the timeline of notices
*
* @return void
*/
function showTimeline()
{
$sitename = common_config('site', 'name');
$sitelogo = (common_config('site', 'logo')) ? common_config('site', 'logo') : Theme::path('logo.png');
// TRANS: Title for timeline with lastest notices with a given tag.
// TRANS: %s is the tag.
$title = sprintf(_("Notices tagged with %s"), $this->tag);
$subtitle = sprintf(
// TRANS: Subtitle for timeline with lastest notices with a given tag.
// TRANS: %1$s is the tag, $2$s is the StatusNet sitename.
_('Updates tagged with %1$s on %2$s!'),
$this->tag,
$sitename
);
$taguribase = TagURI::base();
$id = "tag:$taguribase:TagTimeline:".$this->tag;
$link = common_local_url(
'tag',
array('tag' => $this->tag)
);
$self = $this->getSelfUri();
switch($this->format) {
case 'xml':
$this->showXmlTimeline($this->notices);
break;
case 'rss':
$this->showRssTimeline(
$this->notices,
$title,
$link,
$subtitle,
null,
$sitelogo,
$self
);
break;
case 'atom':
header('Content-Type: application/atom+xml; charset=utf-8');
$atom = new AtomNoticeFeed($this->auth_user);
$atom->setId($id);
$atom->setTitle($title);
$atom->setSubtitle($subtitle);
$atom->setLogo($sitelogo);
$atom->setUpdated('now');
$atom->addLink($link);
$atom->setSelfLink($self);
$atom->addEntryFromNotices($this->notices);
$this->raw($atom->getString());
break;
case 'json':
$this->showJsonTimeline($this->notices);
break;
case 'as':
header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE);
$doc = new ActivityStreamJSONDocument($this->auth_user);
$doc->setTitle($title);
$doc->addLink($link, 'alternate', 'text/html');
$doc->addItemsFromNotices($this->notices);
$this->raw($doc->asString());
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), $code = 404);
break;
}
}
/**
* Get notices
*
* @return array notices
*/
function getNotices()
{
$notice = Notice_tag::getStream($this->tag)->getNotices(($this->page - 1) * $this->count,
$this->count + 1,
$this->since_id,
$this->max_id);
return $notice->fetchAll();
}
/**
* Is this action read only?
*
* @param array $args other arguments
*
* @return boolean true
*/
function isReadOnly($args)
{
return true;
}
/**
* When was this feed last modified?
*
* @return string datestamp of the latest notice in the stream
*/
function lastModified()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
return strtotime($this->notices[0]->created);
}
return null;
}
/**
* An entity tag for this stream
*
* Returns an Etag based on the action name, language, and
* timestamps of the first and last notice in the timeline
*
* @return string etag
*/
function etag()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
$last = count($this->notices) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->auth_user),
common_language(),
$this->tag,
strtotime($this->notices[0]->created),
strtotime($this->notices[$last]->created))
)
. '"';
}
return null;
}
}

View File

@@ -1,409 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show a user's timeline
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author mac65 <mac65@mac65.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('GNUSOCIAL')) {
exit(1);
}
/**
* Returns the most recent notices (default 20) posted by the authenticating
* user. Another user's timeline can be requested via the id parameter. This
* is the API equivalent of the user profile web page.
*
* @category API
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @author Evan Prodromou <evan@status.net>
* @author Jeffery To <jeffery.to@gmail.com>
* @author mac65 <mac65@mac65.com>
* @author Mike Cochrane <mikec@mikenz.geek.nz>
* @author Robin Millette <robin@millette.info>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiTimelineUserAction extends ApiBareAuthAction
{
public $notices = null;
public $next_id = null;
/**
* We expose AtomPub here, so non-GET/HEAD reqs must be read/write.
*
* @param array $args other arguments
*
* @return boolean true
*/
public function isReadOnly($args)
{
return ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD');
}
/**
* When was this feed last modified?
*
* @return string datestamp of the latest notice in the stream
*/
public function lastModified()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
return strtotime($this->notices[0]->created);
}
return null;
}
/**
* An entity tag for this stream
*
* Returns an Etag based on the action name, language, user ID, and
* timestamps of the first and last notice in the timeline
*
* @return string etag
*/
public function etag()
{
if (!empty($this->notices) && (count($this->notices) > 0)) {
$last = count($this->notices) - 1;
return '"' . implode(
':',
array($this->arg('action'),
common_user_cache_hash($this->scoped),
common_language(),
$this->target->getID(),
strtotime($this->notices[0]->created),
strtotime($this->notices[$last]->created))
)
. '"';
}
return null;
}
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
* @throws AuthorizationException
* @throws ClientException
*/
protected function prepare(array $args = [])
{
parent::prepare($args);
$this->target = $this->getTargetProfile($this->arg('id'));
if (!($this->target instanceof Profile)) {
// TRANS: Client error displayed requesting most recent notices for a non-existing user.
$this->clientError(_('No such user.'), 404);
}
if (!$this->target->isLocal()) {
$this->serverError(_('Remote user timelines are not available here yet.'), 501);
}
$this->notices = $this->getNotices();
return true;
}
/**
* Get notices
*
* @return array notices
*/
public function getNotices()
{
$notices = [];
$notice = $this->target->getNotices(
($this->page - 1) * $this->count,
$this->count + 1,
$this->since_id,
$this->max_id,
$this->scoped
);
while ($notice->fetch()) {
if (count($notices) < $this->count) {
$notices[] = clone($notice);
} else {
$this->next_id = $notice->id;
break;
}
}
return $notices;
}
/**
* Handle the request
*
* Just show the notices
*
* @return void
* @throws ClientException
* @throws ServerException
*/
protected function handle()
{
parent::handle();
if ($this->isPost()) {
$this->handlePost();
} else {
$this->showTimeline();
}
}
public function handlePost()
{
if (!$this->scoped instanceof Profile ||
!$this->target->sameAs($this->scoped)) {
// TRANS: Client error displayed trying to add a notice to another user's timeline.
$this->clientError(_('Only the user can add to their own timeline.'), 403);
}
// Only handle posts for Atom
if ($this->format != 'atom') {
// TRANS: Client error displayed when using another format than AtomPub.
$this->clientError(_('Only accept AtomPub for Atom feeds.'));
}
$xml = trim(file_get_contents('php://input'));
if (empty($xml)) {
// TRANS: Client error displayed attempting to post an empty API notice.
$this->clientError(_('Atom post must not be empty.'));
}
$old = error_reporting(error_reporting() & ~(E_WARNING | E_NOTICE));
$dom = new DOMDocument();
$ok = $dom->loadXML($xml);
error_reporting($old);
if (!$ok) {
// TRANS: Client error displayed attempting to post an API that is not well-formed XML.
$this->clientError(_('Atom post must be well-formed XML.'));
}
if ($dom->documentElement->namespaceURI != Activity::ATOM ||
$dom->documentElement->localName != 'entry') {
// TRANS: Client error displayed when not using an Atom entry.
$this->clientError(_('Atom post must be an Atom entry.'));
}
$activity = new Activity($dom->documentElement);
common_debug('AtomPub: Ignoring right now, but this POST was made to collection: ' . $activity->id);
// Reset activity data so we can handle it in the same functions as with OStatus
// because we don't let clients set their own UUIDs... Not sure what AtomPub thinks
// about that though.
$activity->id = null;
$activity->actor = null; // not used anyway, we use $this->target
$activity->objects[0]->id = null;
$stored = null;
if (Event::handle('StartAtomPubNewActivity', array($activity, $this->target, &$stored))) {
// TRANS: Client error displayed when not using the POST verb. Do not translate POST.
throw new ClientException(_('Could not handle this Atom Activity.'));
}
if (!$stored instanceof Notice) {
throw new ServerException('Server did not create a Notice object from handled AtomPub activity.');
}
Event::handle('EndAtomPubNewActivity', array($activity, $this->target, $stored));
header('HTTP/1.1 201 Created');
header("Location: " . common_local_url('ApiStatusesShow', array('id' => $stored->getID(),
'format' => 'atom')));
$this->showSingleAtomStatus($stored);
}
/**
* Show the timeline of notices
*
* @return void
* @throws ClientException
* @throws ServerException
* @throws UserNoProfileException
*/
public function showTimeline()
{
// We'll use the shared params from the Atom stub
// for other feed types.
$atom = new AtomUserNoticeFeed($this->target->getUser(), $this->scoped);
$link = common_local_url(
'showstream',
array('nickname' => $this->target->getNickname())
);
$self = $this->getSelfUri();
// FriendFeed's SUP protocol
// Also added RSS and Atom feeds
$suplink = common_local_url('sup', null, null, $this->target->getID());
header('X-SUP-ID: ' . $suplink);
// paging links
$nextUrl = !empty($this->next_id)
? common_local_url(
'ApiTimelineUser',
array('format' => $this->format,
'id' => $this->target->getID()),
array('max_id' => $this->next_id)
)
: null;
$prevExtra = [];
if (!empty($this->notices)) {
assert($this->notices[0] instanceof Notice);
$prevExtra['since_id'] = $this->notices[0]->id;
}
$prevUrl = common_local_url(
'ApiTimelineUser',
array('format' => $this->format,
'id' => $this->target->getID()),
$prevExtra
);
$firstUrl = common_local_url(
'ApiTimelineUser',
array('format' => $this->format,
'id' => $this->target->getID())
);
switch ($this->format) {
case 'xml':
$this->showXmlTimeline($this->notices);
break;
case 'rss':
$this->showRssTimeline(
$this->notices,
$atom->title,
$link,
$atom->subtitle,
$suplink,
$atom->logo,
$self
);
break;
case 'atom':
header('Content-Type: application/atom+xml; charset=utf-8');
$atom->setId($self);
$atom->setSelfLink($self);
// Add navigation links: next, prev, first
// Note: we use IDs rather than pages for navigation; page boundaries
// change too quickly!
if (!empty($this->next_id)) {
$atom->addLink(
$nextUrl,
array('rel' => 'next',
'type' => 'application/atom+xml')
);
}
if (($this->page > 1 || !empty($this->max_id)) && !empty($this->notices)) {
$atom->addLink(
$prevUrl,
array('rel' => 'prev',
'type' => 'application/atom+xml')
);
}
if ($this->page > 1 || !empty($this->since_id) || !empty($this->max_id)) {
$atom->addLink(
$firstUrl,
array('rel' => 'first',
'type' => 'application/atom+xml')
);
}
$atom->addEntryFromNotices($this->notices);
$this->raw($atom->getString());
break;
case 'json':
$this->showJsonTimeline($this->notices);
break;
case 'as':
header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE);
$doc = new ActivityStreamJSONDocument($this->scoped);
$doc->setTitle($atom->title);
$doc->addLink($link, 'alternate', 'text/html');
$doc->addItemsFromNotices($this->notices);
if (!empty($this->next_id)) {
$doc->addLink(
$nextUrl,
array('rel' => 'next',
'type' => ActivityStreamJSONDocument::CONTENT_TYPE)
);
}
if (($this->page > 1 || !empty($this->max_id)) && !empty($this->notices)) {
$doc->addLink(
$prevUrl,
array('rel' => 'prev',
'type' => ActivityStreamJSONDocument::CONTENT_TYPE)
);
}
if ($this->page > 1 || !empty($this->since_id) || !empty($this->max_id)) {
$doc->addLink(
$firstUrl,
array('rel' => 'first',
'type' => ActivityStreamJSONDocument::CONTENT_TYPE)
);
}
$this->raw($doc->asString());
break;
default:
// TRANS: Client error displayed when coming across a non-supported API method.
$this->clientError(_('API method not found.'), 404);
}
}
}

View File

@@ -1,85 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* List of replies
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Search
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @copyright 2008-2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
/**
* Returns the top ten queries that are currently trending
*
* @category Search
* @package StatusNet
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*
* @see ApiAction
*/
class ApiTrendsAction extends ApiPrivateAuthAction
{
var $callback;
/**
* Initialization.
*
* @param array $args Web and URL arguments
*
* @return boolean false if user doesn't exist
*/
function prepare(array $args = array())
{
parent::prepare($args);
return true;
}
/**
* Handle a request
*
* @param array $args Arguments from $_REQUEST
*
* @return void
*/
function handle()
{
parent::handle();
$this->showTrends();
}
/**
* Output the trends
*
* @return void
*/
function showTrends()
{
// TRANS: Server error for unfinished API method showTrends.
$this->serverError(_('API method under construction.'), 501);
}
}

View File

@@ -1,80 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show a user's followers (subscribers)
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Ouputs the authenticating user's followers (subscribers), each with
* current Twitter-style status inline. They are ordered by the order
* in which they subscribed to the user, 100 at a time.
*
* @category API
* @package StatusNet
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiUserFollowersAction extends ApiSubscriptionsAction
{
/**
* Get the user's subscribers (followers) as an array of profiles
*
* @return array Profiles
*/
protected function getProfiles()
{
$offset = ($this->page - 1) * $this->count;
$limit = $this->count + 1;
$subs = null;
if (isset($this->tag)) {
$subs = $this->target->getTaggedSubscribers(
$this->tag, $offset, $limit
);
} else {
$subs = $this->target->getSubscribers(
$offset,
$limit
);
}
$profiles = array();
while ($subs->fetch()) {
$profiles[] = clone($subs);
}
return $profiles;
}
}

View File

@@ -1,80 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show a user's friends (subscriptions)
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Ouputs the authenticating user's friends (subscriptions), each with
* current Twitter-style status inline. They are ordered by the date
* in which the user subscribed to them, 100 at a time.
*
* @category API
* @package StatusNet
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author Zach Copley <zach@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiUserFriendsAction extends ApiSubscriptionsAction
{
/**
* Get the user's subscriptions (friends) as an array of profiles
*
* @return array Profiles
*/
protected function getProfiles()
{
$offset = ($this->page - 1) * $this->count;
$limit = $this->count + 1;
$subs = null;
if (isset($this->tag)) {
$subs = $this->target->getTaggedSubscriptions(
$this->tag, $offset, $limit
);
} else {
$subs = $this->target->getSubscribed(
$offset,
$limit
);
}
$profiles = array();
while ($subs->fetch()) {
$profiles[] = clone($subs);
}
return $profiles;
}
}

View File

@@ -1,117 +0,0 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Return a user's avatar image
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category API
* @package StatusNet
* @author Brion Vibber <brion@status.net>
* @copyright 2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Ouputs avatar URL for a user, specified by screen name.
* Unlike most API endpoints, this returns an HTTP redirect rather than direct data.
*
* @category API
* @package StatusNet
* @author Brion Vibber <brion@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class ApiUserProfileImageAction extends ApiPrivateAuthAction
{
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$user = User::getKV('nickname', $this->arg('screen_name'));
if (!($user instanceof User)) {
// TRANS: Client error displayed when requesting user information for a non-existing user.
$this->clientError(_('User not found.'), 404);
}
$this->target = $user->getProfile();
$this->size = $this->arg('size');
return true;
}
/**
* Handle the request
*
* Check the format and show the user info
*
* @return void
*/
protected function handle()
{
parent::handle();
$size = $this->avatarSize();
$url = $this->target->avatarUrl($size);
// We don't actually output JSON or XML data -- redirect!
common_redirect($url, 302);
}
/**
* Get the appropriate pixel size for an avatar based on the request...
*
* @return int
*/
private function avatarSize()
{
switch ($this->size) {
case 'mini':
return AVATAR_MINI_SIZE; // 24x24
case 'bigger':
return AVATAR_PROFILE_SIZE; // Twitter does 73x73, but we do 96x96
case 'normal': // fall through
default:
return AVATAR_STREAM_SIZE; // 48x48
}
}
/**
* Return true if read only.
*
* MAY override
*
* @param array $args other arguments
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
return true;
}
}

Some files were not shown because too many files have changed in this diff Show More