forked from GNUsocial/gnu-social
		
	[Poll] Started porting Poll Plugin
This commit is contained in:
		
							
								
								
									
										55
									
								
								plugins/PollPlugin/Controller/NewPoll.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								plugins/PollPlugin/Controller/NewPoll.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| <?php | ||||
|  | ||||
| // {{{ License | ||||
|  | ||||
| // 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/>. | ||||
|  | ||||
| // }}} | ||||
|  | ||||
| namespace Plugin\PollPlugin\Controller; | ||||
|  | ||||
| use App\Core\DB\DB; | ||||
| use App\Core\Form; | ||||
| use function App\Core\I18n\_m; | ||||
| use Plugin\PollPlugin\Entity\Poll; | ||||
| use Symfony\Component\Form\Extension\Core\Type\SubmitType; | ||||
| use Symfony\Component\Form\Extension\Core\Type\TextType; | ||||
| use Symfony\Component\HttpFoundation\Request; | ||||
|  | ||||
| class NewPoll | ||||
| { | ||||
|     public function newpoll(Request $request) | ||||
|     { | ||||
|         $form = Form::create([ | ||||
|             ['Option_1',   TextType::class,   ['label' => _m('Option 1')]], | ||||
|             ['Option_2',   TextType::class,   ['label' => _m('Option 2')]], | ||||
|             ['Option_3',   TextType::class,   ['label' => _m('Option 3')]], | ||||
|             ['Option_4',   TextType::class,   ['label' => _m('Option 4')]], | ||||
|             ['save',    SubmitType::class, ['label' => _m('Submit Poll')]], | ||||
|         ]); | ||||
|  | ||||
|         $form->handleRequest($request); | ||||
|         if ($form->isSubmitted()) { | ||||
|             $data = $form->getData(); | ||||
|         } | ||||
|  | ||||
|         //$test = Poll::create(['id' => '0']); //not working till generating things | ||||
|         //DB::persist($test); | ||||
|         //DB::flush(); | ||||
|  | ||||
|         return ['_template' => 'Poll/newpoll.html.twig', 'form' => $form->createView()]; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										250
									
								
								plugins/PollPlugin/Entity/Poll.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										250
									
								
								plugins/PollPlugin/Entity/Poll.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,250 @@ | ||||
| <?php | ||||
|  | ||||
| // {{{ License | ||||
|  | ||||
| // 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/>. | ||||
|  | ||||
| // }}} | ||||
|  | ||||
| namespace Plugin\PollPlugin\Entity; | ||||
|  | ||||
| use App\Core\Entity; | ||||
| use DateTimeInterface; | ||||
|  | ||||
| class Poll extends Entity | ||||
| { | ||||
|     public int $id;          // char(36) primary key not null -> UUID | ||||
|     public ?string $uri;         // varchar(191)   not 255 because utf8mb4 takes more space | ||||
|     public ?int $profile_id;  // int -> profile.id | ||||
|     public ?string $question;    // text | ||||
|     public ?string $options;     // text; newline(?)-delimited | ||||
|     public ?DateTimeInterface $created;     // datetime | ||||
|  | ||||
|     //need to generate_entity_diagrams/fields | ||||
|  | ||||
|     public function setId($id): self | ||||
|     { | ||||
|         $this->id = $id; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function setCreated(DateTimeInterface $created): self | ||||
|     { | ||||
|         $this->created = $created; | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The One True Thingy that must be defined and declared. | ||||
|      */ | ||||
|     public static function schemaDef(): array | ||||
|     { | ||||
|         return [ | ||||
|             'name'        => 'poll', | ||||
|             'description' => 'Per-notice poll data for Poll plugin', | ||||
|             'fields'      => [ | ||||
|                 'id'         => ['type' => 'char', 'length' => 36, 'not null' => true, 'description' => 'UUID'], //int? | ||||
|                 'uri'        => ['type' => 'varchar', 'length' => 191, 'not null' => true], | ||||
|                 'profile_id' => ['type' => 'int'], //-> gsactor id? | ||||
|                 'question'   => ['type' => 'text'], | ||||
|                 'options'    => ['type' => 'text'], | ||||
|                 'created'    => ['type' => 'datetime', 'not null' => true], | ||||
|             ], | ||||
|             'primary key' => ['id'], | ||||
|             'unique keys' => [ | ||||
|                 'poll_uri_key' => ['uri'], | ||||
|             ], | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     //from old version | ||||
|     /** | ||||
|      * Get a bookmark based on a notice | ||||
|      * | ||||
|      * @param Notice $notice Notice to check for | ||||
|      * | ||||
|      * @return get_called_class found poll or null | ||||
|      */ | ||||
|     /* | ||||
|     public static function getByNotice($notice) | ||||
|     { | ||||
|         return self::getKV('uri', $notice->uri); | ||||
|     } | ||||
|     */ | ||||
|     /* | ||||
|     public function getOptions() | ||||
|     { | ||||
|         return explode("\n", $this->options); | ||||
|     } | ||||
|     */ | ||||
|  | ||||
|     /** | ||||
|      * Is this a valid selection index? | ||||
|      * | ||||
|      * @param int $selection (1-based) | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     /* | ||||
|     public function isValidSelection($selection) | ||||
|     { | ||||
|         if ($selection != intval($selection)) { | ||||
|             return false; | ||||
|         } | ||||
|         if ($selection < 1 || $selection > count($this->getOptions())) { | ||||
|             return false; | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|     */ | ||||
|  | ||||
|     /* | ||||
|     public function getNotice() | ||||
|     { | ||||
|         return Notice::getKV('uri', $this->uri); | ||||
|     } | ||||
|  | ||||
|     public function getUrl() | ||||
|     { | ||||
|         return $this->getNotice()->getUrl(); | ||||
|     }*/ | ||||
|  | ||||
|     /** | ||||
|      * Get the response of a particular user to this poll, if any. | ||||
|      * | ||||
|      * @param Profile $profile | ||||
|      * | ||||
|      * @return get_called_class object or null | ||||
|      */ | ||||
|     /* | ||||
|     public function getResponse(Profile $profile) | ||||
|     { | ||||
|         $pr = Poll_response::pkeyGet(array('poll_id' => $this->id, | ||||
|             'profile_id' => $profile->id)); | ||||
|         return $pr; | ||||
|     } | ||||
| */ | ||||
|     /* | ||||
|     public function countResponses() | ||||
|     { | ||||
|         $pr = new Poll_response(); | ||||
|         $pr->poll_id = $this->id; | ||||
|         $pr->groupBy('selection'); | ||||
|         $pr->selectAdd('count(profile_id) as votes'); | ||||
|         $pr->find(); | ||||
|  | ||||
|         $raw = array(); | ||||
|         while ($pr->fetch()) { | ||||
|             // Votes list 1-based | ||||
|             // Array stores 0-based | ||||
|             $raw[$pr->selection - 1] = $pr->votes; | ||||
|         } | ||||
|  | ||||
|         $counts = array(); | ||||
|         foreach (array_keys($this->getOptions()) as $key) { | ||||
|             if (isset($raw[$key])) { | ||||
|                 $counts[$key] = $raw[$key]; | ||||
|             } else { | ||||
|                 $counts[$key] = 0; | ||||
|             } | ||||
|         } | ||||
|         return $counts; | ||||
|     }*/ | ||||
|  | ||||
|     /** | ||||
|      * Save a new poll notice | ||||
|      * | ||||
|      * @param Profile $profile | ||||
|      * @param string  $question | ||||
|      * @param array   $opts     (poll responses) | ||||
|      * @param null    $options | ||||
|      * | ||||
|      * @throws ClientException | ||||
|      * | ||||
|      * @return Notice saved notice | ||||
|      */ | ||||
|     /* | ||||
|     public static function saveNew($profile, $question, $opts, $options = null) | ||||
|     { | ||||
|         if (empty($options)) { | ||||
|             $options = array(); | ||||
|         } | ||||
|  | ||||
|         $p = new Poll(); | ||||
|  | ||||
|         $p->id = UUID::gen(); | ||||
|         $p->profile_id = $profile->id; | ||||
|         $p->question = $question; | ||||
|         $p->options = implode("\n", $opts); | ||||
|  | ||||
|         if (array_key_exists('created', $options)) { | ||||
|             $p->created = $options['created']; | ||||
|         } else { | ||||
|             $p->created = common_sql_now(); | ||||
|         } | ||||
|  | ||||
|         if (array_key_exists('uri', $options)) { | ||||
|             $p->uri = $options['uri']; | ||||
|         } else { | ||||
|             $p->uri = common_local_url( | ||||
|                 'showpoll', | ||||
|                 array('id' => $p->id) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         common_log(LOG_DEBUG, "Saving poll: $p->id $p->uri"); | ||||
|         $p->insert(); | ||||
|  | ||||
|         // TRANS: Notice content creating a poll. | ||||
|         // TRANS: %1$s is the poll question, %2$s is a link to the poll. | ||||
|         $content = sprintf( | ||||
|             _m('Poll: %1$s %2$s'), | ||||
|             $question, | ||||
|             $p->uri | ||||
|         ); | ||||
|         $link = '<a href="' . htmlspecialchars($p->uri) . '">' . htmlspecialchars($question) . '</a>'; | ||||
|         // TRANS: Rendered version of the notice content creating a poll. | ||||
|         // TRANS: %s is a link to the poll with the question as link description. | ||||
|         $rendered = sprintf(_m('Poll: %s'), $link); | ||||
|  | ||||
|         $tags = array('poll'); | ||||
|         $replies = array(); | ||||
|  | ||||
|         $options = array_merge( | ||||
|             array('urls' => array(), | ||||
|                 'rendered' => $rendered, | ||||
|                 'tags' => $tags, | ||||
|                 'replies' => $replies, | ||||
|                 'object_type' => PollPlugin::POLL_OBJECT), | ||||
|             $options | ||||
|         ); | ||||
|  | ||||
|         if (!array_key_exists('uri', $options)) { | ||||
|             $options['uri'] = $p->uri; | ||||
|         } | ||||
|  | ||||
|         $saved = Notice::saveNew( | ||||
|             $profile->id, | ||||
|             $content, | ||||
|             array_key_exists('source', $options) ? | ||||
|                 $options['source'] : 'web', | ||||
|             $options | ||||
|         ); | ||||
|  | ||||
|         return $saved; | ||||
|     } | ||||
|     */ | ||||
| } | ||||
							
								
								
									
										76
									
								
								plugins/PollPlugin/PollPlugin.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								plugins/PollPlugin/PollPlugin.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| <?php | ||||
| // {{{ License | ||||
|  | ||||
| // 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/>. | ||||
|  | ||||
| // }}} | ||||
|  | ||||
| namespace Plugin\PollPlugin; | ||||
|  | ||||
| use App\Core\Event; | ||||
| use App\Core\Module; | ||||
|  | ||||
| class PollPlugin extends Module | ||||
| { | ||||
|     /** | ||||
|      * Map URLs to actions | ||||
|      * | ||||
|      * @param URLMapper $m path-to-action mapper | ||||
|      * @param mixed     $r | ||||
|      * | ||||
|      * @return bool hook value; true means continue processing, false means stop. | ||||
|      */ | ||||
|     /* | ||||
|         public function onRouterInitialized(URLMapper $m) | ||||
|         { | ||||
|             $m->connect('main/poll/new', | ||||
|                         ['action' => 'newpoll']); | ||||
|  | ||||
|             $m->connect('main/poll/:id', | ||||
|                         ['action' => 'showpoll'], | ||||
|                         ['id' => '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}']); | ||||
|  | ||||
|             $m->connect('main/poll/response/:id', | ||||
|                         ['action' => 'showpollresponse'], | ||||
|                         ['id' => '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}']); | ||||
|  | ||||
|             $m->connect('main/poll/:id/respond', | ||||
|                         ['action' => 'respondpoll'], | ||||
|                         ['id' => '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}']); | ||||
|  | ||||
|             $m->connect('settings/poll', | ||||
|                         ['action' => 'pollsettings']); | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|     */ | ||||
|  | ||||
|     public function onAddRoute($r) | ||||
|     { | ||||
|         $r->connect('newpoll', 'main/poll/new', [Controller\NewPoll::class, 'newpoll']); | ||||
|  | ||||
|         return Event::next; | ||||
|     } | ||||
|     /* | ||||
|         public function onCheckSchema() | ||||
|         { | ||||
|             $schema = Schema::get(); | ||||
|             $schema->ensureTable('poll', Poll::schemaDef()); | ||||
|  | ||||
|             return Event::next; | ||||
|         } | ||||
|     */ | ||||
| } | ||||
							
								
								
									
										20
									
								
								templates/Poll/newpoll.html.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								templates/Poll/newpoll.html.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|     <head> | ||||
|         <meta charset="UTF-8"> | ||||
|         <title>{% block title %}Poll test page!{% endblock %}</title> | ||||
|         {% block stylesheets %}{% endblock %} | ||||
|         <style> | ||||
|           body { | ||||
|               background-color: #333; | ||||
|               color: #ddd; | ||||
|           } | ||||
|         </style> | ||||
|     </head> | ||||
|     <body> | ||||
|         {% block body %}{% endblock %} | ||||
|         {% block javascripts %}{% endblock %} | ||||
|  | ||||
|         {{ form(form) }} | ||||
|     </body> | ||||
| </html> | ||||
		Reference in New Issue
	
	Block a user