Good First Issues in PHP
Explore curated starter issues in high-scoring PHP repositories. Every listed issue belongs to a welcoming repository scored by C-Rankβ’ on PR merge rates, review responsiveness, and first-timer acceptance.
Arm Issue Sniper for fresh PHP beginner issues
Beginner issues in welcoming S/A-Tier repositories get snatched within 15 minutes. Receive instant alerts on Discord, Telegram, or Email the minute a maintainer opens a new task.
Live Good First Issues (30)
Real-Time Open GitHub IssuesDescribe the bug As an instructor, with a staff of TAs assigned to do the bulk of grading, the first time I open the TA grading index page for a gradeable, I always see "Only Assigned Sections" checked. This blocks me from viewing the class and I always uncheck "Only assigned sections". In the future when I return to this gradeable, that option is unchecked. Expected behavior The cookie or local storage we are using to store the user's selection that option is too specific. I believe for most users, the selection to view all sections should be sticky across every gradeable I open in this course, and arguably for it should also be sticky across every course I visit on Submitty. NOTE: We should also revisit the defaults & stored selections for the other options on the TA grading page. We should have a clear decision for which should be global / per course / per gradeable. ALSO: Any PR to address this should make sure we have a clear naming convention for these settings and do approp
What happens On Admin β Users β (a user) β Change Password, type a password in New Password, leave Confirm New Password blank or type something else, and click Save. The page says Password Change Successful. The user's password is now whatever was in the first box, so a typo there goes unnoticed and the user cannot sign in. The self-service form (/v2/user/current/changepassword, which also serves the forced first-login change, and /portal/profile/password) does not read the confirmation box on the server either. Expected The password is not changed, and the form says "You must enter the same password in both boxes". Steps to reproduce Sign in as an administrator and open Admin β Users. Open a user's Change Password. Type NewPassword1 in New Password, leave Confirm New Password blank, and click Save. The page says Password Change Successful. The user can now sign in with NewPassword1. Cause adminChangeUserPassword() in src/admin/routes/system.php and PortalAccountPages::apply
There are plans to simplify the API by renaming the Client to DockerClient and returning results directly instead of promises. In other words, this: $client = new Clue\React\Docker\Client(); $client->imageSearch('clue')->then(function (array $images) { var_dump($images); }); Could potentially look like this: $docker = new Clue\React\Docker\DockerClient(); $images = $docker->imageSearch('clue'); var_dump($images); In line with the upcoming ReactPHP v3, imageSearch() would return the list of images directly, while imageSearchAsync() would return a promise that can be awaited to get the same result. The same applies to all other commands, while the *Stream() methods already return a stream right away and would likely stay as-is. Note that there's no Factory to remove here, as this was already replaced with the simpler Client constructor in v1.0.0 (#49). Renaming it to DockerClient keeps the naming consistent with AmiClient, RedisClient and MysqlClient and makes it more obvious what
What problem are you trying to solve with Submitty I am an instructor and I receive an email that a post has been made to a grade inquiry thread, but there is no link to the specific gradeable + student if I want to review the materials and contribute to the discussion Describe the way you'd like to solve this problem Let's add a link to the grade inquiry emails & notifications. If I'm a student and there is activity on my grade inquiry, the link should be to the submission page for that gradeable. If I'm a full access grader or instructor, the link should be to the TA grading page for that gradeable and to the specific student. NOTE: Currently the email does not include the name of the student nor the name of the grader. Let's keep it that way. The link to the specific students assignment should also not include the name of the student but should use the anonymous id. (The name of the student should not be in the email in any way.)
What problem does this address? Now that we have :ALOT: of experiements, the AI Status widget has grown quite tall. What is your proposed solution? Perhaps we: if less than or equal to 5 experiments are enabled list those out if more than 5 experiments are enabled, note "N experiments enabled" note "X experiments not enabled" Why is this important to you? No response I have searched existing issues and this is not a duplicate. Yes
Goal Make LibreSign Unified Search pagination terminate correctly and return stable results. Starting points lib/Search/FileSearchProvider.php::search() lib/Db/SignRequestMapper.php::getFilesToSearchProvider() Nextcloud OCP\Search\IProvider, ISearchQuery and SearchResult Requirements Handle supported integer, string and null cursor values safely. Reject invalid or overflowing offsets before database access. Respect the requested result limit. Fetch one additional record when needed to determine whether a next page exists. Return SearchResult::complete() when no next page exists. Return SearchResult::paginated() only when additional records remain. Make ordering deterministic using creation time and a unique ID as a tie-breaker. Apply SQL offsets directly rather than deriving a fractional page number. Preserve sorting behavior in other LibreSign file lists. Acceptance criteria Empty, partial, exact-limit and multi-page datasets return correct pagination metadata. Equal timestamps
What problem are you trying to solve with Submitty The TA grading index page shows the students registration section. But it does not display the students registration subsection. Describe the way you'd like to solve this problem Let's add registration subsection to the toggle columns options for the TA grading index page. Since it is a rarely used feature, let's set it to default to 'off' for display. When toggled on, there should be a separate column for registration subsection. See also #13328
Describe your feature request precisely Hi, the current "mass email" feature (used by sysadmins) lacks rich text formatting options (e.g., bold, italics, bullet points), unlike the onboarding emails or admin-to-team communications, which already support this. Tomorrow, we upgrade to v6.0.6 (!) and I would have liked to highlight it a bit :-) Thanks. Have a good day, Oana Pro Support No response
What problem does this address? Sites that cover a subject over months or years build up a large body of work on it, but that work is spread across many separate posts. Category and tag archives list those posts newest-first with no context. A reader who lands on one cannot quickly tell how the subject developed, what the key moments were, where to start reading, or even really that the site is particularly knowledgeable on a given topic or even a summary of the topic (besides a breadth of related posts). The same gap affects AI-powered search and answer tools. When someone asks one of these tools to explain a subject, the tool looks for a single, well-organized source that covers it from start to finish. If a site's coverage only exists as scattered posts, these tools often point to another site that has organized the subject better, even when the original site did the reporting. Editors can hand-build overview pages for their most important subjects, but that does not scale, and
Tip Help move this idea forward Use the π reaction to show support for this feature. Avoid commenting unless you have relevant information to add; unnecessary comments create noise for subscribers. Subscribe to receive notifications about status changes and new comments. The occ taskprocessing:list command does not have a limit on the no. of results returned, when the list is long, it can take a while to render all the tasks with every detail about them. A new option can be added that has a default of say 10 to only fetch these many tasks from the DB and output that only. The command is defined here https://github.com/nextcloud/server/blob/7ddb822c798c2e65634b2c79dbb323711a961fa5/core/Command/TaskProcessing/ListCommand.php
Describe the bug If the marks for the TA grading component are long (many words) the wrapping, the wrapping is buggy and hard to read. The two black blobs below are the names of peer graders: The numbers 1,2,3,... under the left-most column of boxes are the hot keys for choosing those marks. not sure why they are wrapping so terribly. I don't know if the mark numbers are helpful or not in this view. The vertical spacing is awkward for these long mark names when the panel is narrow. Maybe we need thin horizontal lines between them. And perhaps the boxes should be centered vertically? And when we have lots of peer graders, the text of the marks is off screen to the right and the horizontal scrolling is not great. maybe the marks should be "sticky" and we should just the peers should scroll? Expected behavior I'm not sure what the best design is, but it shoud be tested with marks that have lengthy text AND a large number of peers giving feedback (10 or even 30 or more!). It
What problem does this address? Learn WordPress now has a comprehensive AI-Powered WordPress course covering how to configure and use the AI plugin, including provider setup, editorial tools, alt text generation, comment moderation, request logging, connector approvals, and the underlying AI building blocks. We should make this resource easier for AI plugin users to discover so that they have an obvious path from installing and configuring the AI plugin to learning how its features work and how they fit into the broader WordPress AI ecosystem. What is your proposed solution? Add a link to the course from the readmes and/or other relevant documentation Add a contextual link from the plugin's Settings > AI screen, such as a "Learn how to use WordPress AI" help link (perhaps shorter copy so it fits in the header?) Consider whether individual settings or features should link directly to relevant course lessons where useful Why is this important to you? No response I have searched exi
Please describe the new functionality as best as you can. Is your feature request related to a problem? Please describe. Currently, dynamic footers allow conditional rendering based on even/odd pages ($OE parameter accepting 'O', 'E', or '' / 0 / 1 / 2). However, when configuring a specific footer for the last page of a document, mPDF does not take into account the custom dimensions or margin constraints of that final footer during the initial layout calculation. This often leads to layout overlapping, incorrect total page count estimates, or text overflowing onto an unexpected extra page because the engine calculated page heights using the standard/odd/even footer margin instead of the last page's specific footer height. Describe the solution you'd like Extend the $OE (Odd/Even) parameter in SetHTMLFooter() (and related footer methods like SetFooter()) to accept an 'L' value (for Last page), similar to how 'O' and 'E' operate. When 'L' is specified (e.g., $mpdf->SetHTMLFooter($htmlFoo
Contexto Na retrospectiva mensal, o slide "Quem viveu no voice" (discord.voice_board) Γ s vezes mostra o snowflake do Discord no lugar do nome do membro. A pessoa Γ© contada corretamente: o registro de voice aponta para a ExternalIdentity certa, e essa identidade estΓ‘ ligada ao User certo. O erro estΓ‘ sΓ³ no rΓ³tulo. Causa DiscordSource::displayNames() (app-modules/activity/src/Retrospective/DiscordSource.php) monta o nome sΓ³ a partir de metadata.username, no topo do JSON: return [$identity->id => $username ?? $identity->external_account_id ?? 'AnΓ΄nimo']; HΓ‘ dois grupos de identidades Discord em que essa chave fica vazia: Perfis importados antes de cb6f0f38. O import gravou o payload bruto do Discord. O username ficou sΓ³ em metadata.user.username. O DiscordIdentityMetadata::mergeProfile() atual jΓ‘ grava username no topo, entΓ£o sΓ³ as linhas antigas tΓͺm esse problema. Identidades sem nome nenhum no metadata. SΓ£o, por exemplo, contas migradas de providers com username nulo. O
WP_Document_Revisions_Recently_Revised_Widget::update() reads $new_instance['show_thumb'], show_descr, show_author, show_pdf and new_tab without checking that the keys exist (L254-L258). A real classic-widget form submission leaves out unchecked checkboxes, so saving the widget with any of these unchecked logs PHP 8 "Undefined array key" warnings. The post_status_* checkboxes in the same method already use isset() (L262). The existing test_update_function() (tests/class-test-wp-document-revisions-widget.php#L576) passes every key, so it doesn't catch this. Acceptance criteria: Saving with any of the five checkboxes unchecked (the key missing from $new_instance) stores false for it and raises no warning. Checked boxes still store true. A PHPUnit test calls update() with those keys missing and asserts the stored values. Pointer: in update(), use ! empty( $new_instance['show_thumb'] ) for each of the five. Don't use isset(): the existing test passes false for some keys and expects false
docs/shortcodes.md (and L123) says boolean parameters "can be entered without a value (with default value true)". Two block "transform from shortcode" handlers do the opposite and treat a bare flag as false: src/blocks/revisions-shortcode/index.js#L48-L52: if ( parm.length === 1 || parm[ 1 ] === 'false' ) { snew_tab = false; } src/blocks/document-preview/index.js#L39-L43: the same pattern for show_download On the server side, both attributes default to true, and since #812 the PHP shortcode also reads a bare new_tab as true. So [document_revisions id="1" new_tab] opens links in a new tab as a shortcode but stops doing so after "Transform to block". Likewise, [document_preview id="1" show_download] shows the download link as a shortcode and hides it as a block. The Document List transform already handles this correctly with parm.length === 2 && parm[ 1 ] === 'false' (src/blocks/documents-shortcode/index.js#L113-L118), and its test asserts that a bare new_tab stays true (tests/js/wpdr-
Two related bugs in the [document_preview] shortcode, both in wpdr_document_preview_display(). They change the same lines, so they're filed together. 1. [document_preview] with no attributes causes a fatal error. When a shortcode has no attributes, WordPress passes an empty string, not an array. The method declares array $atts, so PHP throws a TypeError and the page shows a critical error instead of the plugin's normal "This is not a valid document." message. The other two shortcodes in this class already guard against this, with the comment "WordPress passes empty string when shortcode has no attributes": see revisions_shortcode() (L116-L121) and documents_shortcode() (L221-L226). The block's render callback always passes an array, so only the shortcode form is affected. 2. A bare show_title flag is ignored. docs/shortcodes.md says the preview's boolean parameters "can be entered without a value (with default value true)". But [document_preview id="100" show_title] shows no title. Wor
Eight hooks added in 5.6.0 are in the code and the changelog, but they're missing from the hook reference in docs/filters.md and docs/actions.md, so developers can't find them there. Missing filters, all in includes/trait-wp-document-revisions-file-handler.php: document_serve_redirect_url (L176-L191) document_compressible_mimetypes (L596-L606) document_allowed_mimes (L645-L658) document_upload_size_limit (L672-L684) document_serve_sendfile_header (L1170-L1184) document_serve_sendfile_path (L1189-L1204) Missing actions, in the same file: document_upload_start (L927-L939) document_upload_end (L724-L732) Each hook already has a full docblock (purpose, parameters, @since 5.6.0), so you can write each docs entry from its docblock. The plugin hides where document files are stored (randomized file names, downloads served through WordPress), and the document_serve_* filters bypass that, so their entries need to say what they expose (see Neil's comment). #824 adds this to the docblocks; wai
The performance-monitoring example in docs/examples/optimization-examples.php:95-112 hooks jekyll_export_complete, but the plugin never fires that action. The only one it fires is jekyll_export, at the start (jekyll-exporter.php:715). Anyone who copies the example never gets the log line and is left with a stray option in wp_options. Pointer: fire it right after $this->cleanup() in export() (L727). That runs on both the browser-download path and the WP-CLI path. On the download path the zip has already been sent, so wrap the call in ob_start() / ob_end_clean() the way the jekyll_export call is wrapped (L714-721). Fire it inside the try block so a failed export never reaches it. Acceptance criteria: the action fires once after a successful export on both paths and doesn't fire when the export fails. A test covers it, the docs list the hook, and readme.txt is regenerated if docs/ changes.
Several per-post filters receive only the value being filtered, not the post it came from, so you can't customize output per post. The affected filters are: jekyll_export_meta (jekyll-exporter.php:280) jekyll_export_terms (L318) jekyll_export_markdown and jekyll_export_content (L495-496) jekyll_export_html and jekyll_export_content in html_fallback() (L506-509) Only jekyll_export_post_meta passes $post today (L532). Adding $post as a second argument is backward compatible: WordPress only passes it to callbacks registered with accepted_args of 2 or more. Acceptance criteria: each filter above receives $post as its second argument, and html_fallback() takes $post from its caller. PHPUnit tests show that a two-argument callback gets the right post. docs/custom-fields.md:9 is updated, and readme.txt is regenerated with script/build-readme.
Summary In the Family Editor (add mode) the Country dropdown has no blank option. When neither sDefaultCountry nor sChurchCountry is set, the first country in the list (Afghanistan) is pre-selected, so a new family is saved with a country nobody chose. Steps Clear Default Country (People Settings > New Record Defaults) and the church country. Open Add Family. Country shows Afghanistan. Expected A blank or "select a country" choice, so the address is saved without a country. That also keeps geocoding honest: the US Census provider is only asked when a country resolves to the US. Notes #10276 added the church-address fallback (AddressDefaults), so this only happens when both are blank. Selection is built in DropdownManager.js from data-system-default; the Person editor uses the same dropdown. Acceptance A blank first option when no default resolves, and a Cypress case that checks it.
documents_widget_block() builds $merged_sizes (it runs fallback_intermediate_image_sizes and calls get_intermediate_image_sizes()) and then never uses it: https://github.com/wp-document-revisions/wp-document-revisions/blob/60f67c2e/includes/class-wp-document-revisions-recently-revised-widget.php#L300-L320 That means every widgets_init does useless work and fires a core filter for no reason, which could surprise anyone hooked into it. Fix: delete those lines. Before doing so, check with git log -L whether the value used to be passed to the block registration. Found while mapping the existing blocks for #796. π€ Generated with Claude Code
post_password was taken out of the shortcode's allowed query keys in 75bc9c6 ("Only list documents the viewer can read"), because querying by password is a way to probe for it. docs/shortcodes.md still lists it: https://github.com/wp-document-revisions/wp-document-revisions/blob/60f67c2e/docs/shortcodes.md?plain=1#L19 Fix: remove post_password from that list (keep has_password), then run script/build-readme if the readme quotes this section. Found while mapping the existing blocks for #796. π€ Generated with Claude Code
Describe the bug Shows overdue assignment from gradeables tab (when the assignment IS NOT overdue). Shows right on both assignment/calendar view. Expected behavior To Reproduce Steps to reproduce the behavior: 1. 2. 3. 4. See error Configuration OS: [e.g. Windows, Linux, ...] Browser [e.g. Chrome, Safari] Screenshots Additional context
Describe your feature request precisely Hello, I hope that I don't duplicate this feature request but I have not found it anywhere. I very much appreciate the highlighting of "required" extra fields, but it would be nice if this could also be applied to the non-text / non-number extra fields e.g.: Dropdown menu Radio button (when blank on duplicate) The same applies to Checkboxes, but I know that this is a bit tricky as "not-checked" is also an option. Maybe there is some sort of "has never been edited" flag? Thank you very much! Pro Support No response
The native DateTimeImmutable has the NoDiscard attribute on modifier methods such as modify() and add(), which is helpful because you get a warning if you make a mistake and think you are working with a mutable instance and don't catch the result. default.WARNING: The return value of method DateTimeImmutable::modify() should either be used or intentionally ignored by casting it as (void), as DateTimeImmutable::modify() does not modify the object itself { "code": "E_WARNING", "message": "The return value of method DateTimeImmutable::modify() should either be used or intentionally ignored by casting it as (void), as DateTimeImmutable::modify() does not modify the object itself", When I swap DateTimeImmutable for CarbonImmutable, though, no such warning seems to be emitted? I caused a bug in the last week because I swapped some code to use a CarbonImmutable, but missed a section that was modifying the previously mutable instance, which would have been nice to highlight! I was won
Follow-up to #328 (fixes #325). Task: document the WordPress version dependency The fullscreen editor fix in admin/css/wpfaevent-admin.css targets block-editor internal class names: .edit-post-meta-boxes-main .edit-post-meta-boxes-main__liner .interface-interface-skeleton__content These are not a stable WordPress API and have been renamed in past releases. If they change again, the fullscreen bug from #325 will silently return. Extend the existing comment above these rules to say they were verified against WordPress 7.1, and link back to #325 so the reason for the rules is easy to trace. Acceptance criteria CSS comment mentions the WP version the selectors were verified on and references #325 No change in behaviour: fullscreen editor still works on the Event edit screen (Venue / Transportation / Hotel information) and the Speaker edit screen (Biography) Optional, not required for this issue Each rule is currently written once for .post-type-wpfa_event and once for .post-type-wpfa_s
What problem are you trying to solve with Submitty When the instructor is running a poll on Submini polls, we do not auto-update the number of students who have responded to that poll. Describe the way you'd like to solve this problem In the example above, the '96' should increment when a new student replies. But currently, the instructor needs to manually reload the whole page to see that update. This PR should use the websockets interface so this is done efficiently.
Describe the bug We have a feature in the TA grading interface, "who got this mark", that allows a grader to see the other students who received this mark. https://submitty.org/grader/rubric_grading/rubric_components_and_marks#who-got-this-common-mark This feature should only list students that the grader is allowed to view/grade. And it should be anonymous if the grader is a limited access grader or peer grader who is locked into anonymous mode or if the grader has chosen to be in anonymous mode. I'm not sure if this feature is useful/necessary in peer grading mode. If the peer is only assigned to grade a few students, it is unnecessary and should probably be hidden from view. If a peer is grading lots of people / the whole class, then maybe it is useful, but maybe it is just visual clutter confusion. Regardless, we have a bug. This is what happens when a peer who is grading in double-blind mode (locked anonymous) clicks on that icon: Expected behavior Short term - Let's hide thi
Describe your feature request precisely Add text somewhere to indicate that an entry was made from a template, including the template name. Pro Support No response
Top PHP Repositories with Beginner Issues (20)
Updated Daily via GitHub GraphQL:notebook: eLabFTW is the most popular open source electronic lab notebook for research labs.
AI-powered Moodle plugin for tutoring, quizzes, mind maps, RAG course materials and more.
Homework Submission, Automated Grading, and TA grading system.
GLPI is a Free Asset and IT Management Software package, Data center management, ITIL Service Desk, licenses tracking and software auditing.
:page_with_curl: The main project repository
Mbin: a federated content aggregator, voting, discussion and microblogging platform
Shopware 6 is an open commerce platform based on Symfony Framework and Vue and supported by a worldwide community and more than 3.100 community extensions
Core framework that implements the functionality of the Sulu content management system
The Symfony PHP framework
Control how your documents get signed
The most popular open source electronic health records and medical practice management solution.
A customizable, open-source ecommerce platform built on WordPress. Build any commerce solution you can imagine.
Laravel is a web application framework with expressive, elegant syntax.
βοΈ Nextcloud server, a safe home for all your data
DOMjudge programming contest jury system
AI features and experiments for WordPress. Modular framework for testing AI capabilities.
Travian T3.6 with user-configurable features (enable/disable).
Contao Open Source CMS
Plataforma da HeartDevs
Open Source PHP Framework (originally from EllisLab)
How to make your first PHP open-source pull request
Finding approachable Good First Issues in PHP allows you to build real-world software engineering experience. Instead of submitting PRs to abandoned repositories, GetMerged verifies maintainer review speeds and first-timer acceptance rates before you write a single line of code.
Select any issue above to claim it directly on GitHub, or click a repository to inspect full maintainer review turnaround metrics and triage guidance!
Get this week's top welcoming repos + fresh Good First Issues for PHP
Free weekly email, scoped to PHP. No account needed - confirm once and unsubscribe anytime.