
Everything posted by Mark
-
Error Code List
That isn't an error that should happen - it occurs from an exception being caught in the multi-redirect code, in this case somewhere along the line it's trying to access the contents of a file which doesn't exist - which may indicate there is an error in uploading the image. I would recommend contacting support to help you resolve that issue - a log is written with more information if that error occurs, so the support team will be able to look at your logs to get a better idea of what happened there.
-
4.1.8.1
This is a very small release to fix a few rather annoying issues from 4.1.8. Sorry about that Fixes an issue where incoming emails were not being received correctly. Fixes an issue where guests could do a partial account registration which could cause some confusion to the administrator when editing. Fixes an issue where the AdminCP dashboard may incorrectly report tasks aren't running when they actually are.
- 4.1.8
-
Terminology
Products Products are the things which are available in the store for users to buy. Most Products are Normal Products, but if you want to sell Advertisements or Hosting Plans, these are also types of Products. For more information about how to create Products, see Products & Purchases. Invoices Invoices, or Orders as they are called on the front-end, are the things that say a particular user is buying particular things. They can be created in 3 ways: When a user clicks "Checkout" in the Store, an Invoice is created. If a member has any Purchases which have renewal terms, an Invoice is created automatically when the renewal payment is due. An administrator can create Invoices manually in the AdminCP. An Invoice is made up of items which will usually be Products but could also include paid files from the Downloads application, donations, or anything else a user can pay for. Any shipping costs, adjustments for coupons, etc. will also be shown on the Invoice. Invoices will always have one of the following statuses: Paid - the user has paid the invoice (using Transactions) or the invoice has manually been marked as paid by an administrator. Pending - the user has not yet paid the invoice. Expired - the user did not pay for the invoice within the time period set by the "Invoices must be paid within" setting (AdminCP > Commerce > Invoices > Invoice Settings) and so the invoice is expired and they cannot submit payment. An administrator could resend the Invoice in the AdminCP to put it back to Pending. Canceled - either the user, or an administrator, manually canceled the invoice. Payment may have never been submitted, or may have been refunded. Transactions A Transaction is how a user pays for an Invoice. For example, when a user submits their card details, that creates a Transaction. An Invoice may have more than one transaction, for example, if their card is declined and then they use a different card, the Invoice will have two Transactions associated with it: one failed, and one approved. Transactions are usually associated with a Payment Method which processed (or attempted to process) the payment (for example PayPal, Stripe or Authorize.Net). However, if the user chooses to use credit on their account to pay, this will also show as a Transaction with Account Credit if specified as the method. In addition to Transactions created by the user checking out, they can also be created automatically. If a user has Purchase with renewal terms and also has a credit card on file, a PayPal Billing Agreement, or account credit when the renewal term is due, a Transaction to take that payment will be generated automatically when the Invoice is generated. Transactions will always have one of the following statuses: Approved - the payment was received successfully. Held for approval - usually means that the payment was received successfully, but was halted by a Fraud Rule. An administrator will need to manually approve or void/refund*. This status is sometimes also used if there was an error in the Payment Method and the system is not sure whether the payment was received or not - an administrator will need to confirm and either approve or refund the Transaction. Under review - the Transaction was previously Held for approval and an administrator has marked it for review. An administrator will need to manually approve or void/refund*. Failed - the payment was unsuccessful (for example, their card was declined for insufficient funds) or was voided by an administrator. Refunded - the payment has been refunded by an administrator. Partially Refunded - the payment was successful, however the user has been given a partial refund, so it's status is partially Approved and partially Refunded. Waiting - the user has indicated they will pay via a manual method (for example, post a check or send a bank wire). The administrator should mark this as approved once they receive payment, or cancel it if payment is not received. Pending - it is unusual to see this status, but indicates that the user submitted payment and the payment method has not yet confirmed or denied receiving it. It will automatically change to one of the above statuses or be deleted automatically. * Sometimes you will see a "Void" option for a Transaction and other times, "Refund". When a user makes a payment, most Payment Methods will first authorize the transaction (meaning they are holding the funds), but not capture it until it has passed the Fraud Rules check. This is to avoid unnecessary refund fees for you. In this state, you will see the "Void" option, which will cancel the payment completely, while the "Approve" option will capture and complete the payment. If the transaction has already been captured (some Payment Methods don't support separate authorize and capture, and some have a limit on how long a Transaction can be in this state for) you will see a "Refund" option. Shipments If an Invoice contains physical Products which need to be shipped, then once the Invoice is paid, Shipments are generated. These contain the items and quantities to be shipped, the Shipping Rate to ship them by, and the shipping address. Sometimes more than one may be generated, for example, if the user is purchasing two different Products with different Shipping Rates. Shipments will always have one of the following statuses: Shipped - the shipment has been sent. Pending - the shipment is waiting to be shipped. Once it has been sent, an Administrator should mark is as Shipped. Canceled - the shipment has been canceled, it is possible that payment was refunded (and therefore the Invoice was no longer marked Paid) before the shipment was sent, or it has been manually marked Canceled by an administrator. Purchases Once an Invoice has been marked as Paid, the details of any Products, and certain other items (for example, Files in the Downloads application) are stored as a Purchase. A Purchase may have an expiry date and renewal term, which will cause renewal Invoices to be generated automatically.
-
4.1.7
This is a maintenance release to fix reported issues. Please note that in this release we have updated the copyright data in many source files. This means that if you are upgrading through the Admin CP the update will take slightly longer to download and extract than normal.
-
4.1.6.1
This is a maintenance release to fix reported issues.
-
Error Code List
We don't have a list - the error codes are just so we can do a search of the code and find it easily. We try to make the error messages themselves provide as much information as necessary. If you post the code here though, I can look it up for you.
-
Broken quotes, images, links, avatar? Here's My Fixes
Everything should transition fine (though note that posts convert in the background after upgrading). I would not recommend running those queries, some are far too broad in scope and many will interfere with the correct converting of post data. If, after upgrading, and posts have finished converting, you are experiencing issues, please submit a support request so we can figure out what's happening and include a fix in the software itself if necessary.
- Test
-
4.0 - Delta Updates
IPS Community Suite 4.0 is nearly here, and we'll be distributing betas very soon. But 4.0 is really just the beginning; with the new tightly integrated, one-version suite of applications, we're already starting to think about all of the features we'd like to add in the future. This brings us nicely to the final 4.0 feature we'd like to talk about: the upgrade system. In 4.0, when a new version is released, you'll see a message like this pop up in the Admin CP: Clicking the "Download" button will allow you download, right from the Admin CP, a zip file with the new version. This zip file will contain just the changed the files from the version you're using (in technical terms, this is called a delta update) to save time and bandwidth when uploading the new version to your server. The system automatically knows what apps you have installed (so you don't have to download a separate zip for each application) and even knows if you've renamed your AdminCP directory and accommodates for that. Here's a video of the process in action:
-
Geolocation on user login via Smartphone GPS or IP in IPS 4.0
If you're a developer, you can also use the GPS of mobile devices quite easily (we actually use this in IP.Nexus to make the address input field autocomplete, you usually only need to enter your house number and it knows the rest), though I wouldn't recommend it for things like location-based advertising. With GPS location, it requires both the user to have GPS-compatible hardware, and them to specifically allow access. While that's fine for specific cases, most users aren't going to allow access to their precise location unless they know what you want it for. And for things like location-based advertising, getting it based on their IP is specific enough (I assume you're going to do ads based on their country, or maybe state, but you're not going to show different ads to different streets, presumably ). The methods available are: /* IP address */ IPSGeoLocation::getByIp( $ipAddress ); /* Latitude and longitude (such as returned by the GPS) */ IPSGeoLocation::getByLatLong( $latitude, $longitude ); /* Manually */ $geolocation = new IPSGeoLocation; $geolocation->addressLines = array( '123 Fake St.' ); $geolocation->city = 'City'; $geolocation->country = 'US'; So, if you wanted it, it's there. You'd just need to write the JS to ask the user for permission and post the values (which is just a couple lines of JS).
-
Get Ready For IPS 4.0!
IPS Community Suite 4.0, the most significant update to IP.Board and the rest of our apps we've ever made, is fast approaching a state where we'll be ready for a public preview and, soon after that, public beta testing! We know most of you are just as excited as we are about this and can't wait to try it out. With 4.0, we've made some significant leaps in terms of modernization, and it's possible that you might need to do some preparation before you're ready to install it. Notably, our minimum PHP and MySQL versions have gone up. It's the first time we've needed you to do this in 6 years, and the versions we need you to have have been around for a long time, we're not requiring the latest versions. In addition, 4.0 is UTF-8 only (if you don't know what that is, it's a way text can be stored in your database which you may or may not be using at the moment) and while the 4.0 upgrade process will ask you to convert your database if you're not already using it, this is a moderately time-consuming process, so if you convert your database now, it's one less thing to worry about on upgrade day. To make this process as easy as possible, we have created a little script which you can upload to your server to test if you're ready. Download Now
-
4.0: Quick Translating
A while ago I blogged about some of the internationalization and localization changes in 4.0. One of the things I mentioned is a "Visual Language Editor" which allows you to quickly change any of the verbiage used throughout the suite just by clicking on a word of phrase. Not only is the really useful for those who want to translate the IPS Community Suite into another language, it can also be used to easily change words and phrases as you like (for example if you want a link to say "Register" rather than "Sign up") - it can even be used to rename forums, categories, etc. Before I couldn't show you it in action as we weren't quite ready to show the front-end interface but now here's a video of the feature in action:
-
4.0 - Moderation Part 5: Warnings
Effective moderation features are essential for online communities. Forums, blog entries and member-to-member messaging are particularly attractive for spam bots and nuisance users alike. IPS Social Suite has always been best in class when it comes to moderation features with features like the free IPS Spam Service that are completely unmatched by other web applications. Over this series of 5 blog entries I'm going to introduce you to some of the new moderation features in the IPS Community Suite 4.0. Part 1: Setting up moderators Part 2: Approval Queue Part 3: Reports Part 4: Effective Moderation Part 5: Warnings Introduction A lot of what I'm going to cover in this blog entry is similar to the warning system in 3.x which was recently overhauled. Since warnings and moderations are such an important aspect of running a community though, I wanted to reintroduce the system, showing off the new UI for 4.0 and highlighting some of the tweaks that have been made. The warnings system in the IPS Community Suite is point-based. When issuing a warning to a member, you select a reason, and each reason is tied to a number of points, and then when a member reaches a certain number of points, an action (such as to ban them from the site) is taken. This is the setup page for reasons - I've set up each one to give one point which is never removed. For each reason, I can choose if moderators can override that or not: This is the setup page for actions: I've set up a number of actions so that the following flow happens: You can control whether members can see their previous warnings or not. Moderator Permissions For each moderator you can control is they can see, issue and revoke warnings, and control how often they can give warnings: Viewing Warnings You will be able to see the current warning points for a member from their hover card (which shows whenever you hover your mouse over their name throughout the suite) and can see the details in their profile. Clicking on a warning brings up the details which show a link to the content the user posted which prompted the warning, the notes both for the member and for other moderators, and lists the actions taken (points given, if the member was suspended, etc.): In addition, when viewing content (posts, comments, etc.) if that post prompted a warning, this will be shown to moderators: Issuing Warnings When issuing a warning, selecting a reason will automatically fill in the number of points and actions to take based on the number of points the member already has (these can be changed if the administrator has allowed it). You can clearly see the pre-defined actions for each point level on the right. You can optionally add notes, both a note for the member and for other moderators. Acknowledging Warnings You can optionally set the system so that members have to acknowledge a warning before they can post again. When this is the case, the member will se a message on every page: Viewing the warning details will have a button allowing the member to acknowledge the warning: Even if you do not require warnings to be specifically acknowledged - members who have restrictions applied to their account (are on moderator queue, are restricted from posting or are banned) can clearly see this and the reason why. For example, this is what a member who is on moderator queue sees when making a comment: Revoking Warnings A new feature in 4.0 is that warnings can be revoked. You can reverse all the actions of the warning, or just delete the record of it: [*]On the first warning, nothing happens (it's a verbal warning only) [*]On the second warning, all posts the user makes for the next day will need to be approved by a moderator. [*]On the third warning, the user will be banned for one day and all posts the user makes for the next week will need to be approved by a moderator. [*]On the fourth warning, the user will be banned for a week. [*]On the fifth warning, the user will be permanently banned.
-
4.0 - Messenger
I can distinctly remember 5 years ago reading a blog entry on this site about the "personal conversations" feature in IP.Board 3.0, which we were working on at the time. Up until then, the messenger system in community software and other websites was much like email - you sent one message at a time, with little continuity between messages. We were one of the first, on the entire of the web, to introduce what we called "personal conversations" - a sort of "private topic" between invited members - it was a really exciting idea back then. For 4.0, we wanted to really focus on the experience of using the messenger - making it super fast and easy to compose, navigate and participate in conversations. Starting a conversation When browsing the site, you'll see a messenger icon at the top of every screen just like you do now. When hitting the "Compose Now" button inside though, the form to send your message will appear as a modal window, and when you send, it will disappear again with no page reload. This makes it incredibly fast and easy to send a message from wherever you are, without interrupting your flow. You can also send a message to a specific member by hovering over their name wherever you see it on the site and clicking the "Send Message" button in the hover card that shows. Browsing conversations We've completely redesigned the main messenger pages. You now see a (infinitely scrolling) list of all your messages on the left-side. Clicking on any message opens it up in the main pane. All the common actions are enhanced with AJAX so you can open a conversation, add a user and reply all really quickly. Mobile We've not forgotten about mobile devices! The new responsive design in IPS 4.0 means the whole messenger works and looks great whether you're on a desktop or on your phone. Summary We recognise that when members send a new message, it is often as a response to content read in all areas of the suite. You can now send messages in place without disrupting your flow. We have improved all aspects of sending, receiving and managing messages and are confident these changes will make communicating with other members in private simpler and faster.
-
4.0 - IP.Downloads Category Management
Copying Settings Sometimes you need to change the same setting across multiple categories. For example, let's say up until now I've not allowed comments on files and now I want to enable it for most categories. In IP.Downloads for 3.x, I'd have to go into each category one by one and toggle the setting on. In 4.x, when editing a category, each setting has a "Copy" button next to it, when opens a window asking which categories to copy that setting value to, so I can make the change to one category and then copy it to others (or all) quickly. This feature is also available when editing things in other applications, such as forums in IP.Board or products in IP.Nexus. New Settings We've moved some settings which were previously global settings into per-category settings to give you even greater control over your community: "Require approval of comments" "Log all downloads" and "Prune download logs" - we also added a new per-category setting: "Allow file submitter to view log?" "Allowed file extensions" (this used to be managed using complicated "Mime Type Masks" - now you can just provide the extensions which are allowed in that category, or allow any file type). "Enable versioning control" and "Number of revisions to keep"
-
4.0 - Moderation Part 4: Effective Moderation
Effective moderation features are essential for online communities. Forums, blog entries and member-to-member messaging are particularly attractive for spam bots and nuisance users alike. IPS Social Suite has always been best in class when it comes to moderation features with features like the free IPS Spam Service that are completely unmatched by other web applications. Over this series of 5 blog entries I'm going to introduce you to some of the new moderation features in the IPS Community Suite 4.0. Part 1: Setting up moderators Part 2: Approval Queue Part 3: Reports Part 4: Effective Moderation Part 5: Warnings Multi-moderation It's really important that moderators can quickly take action against undesirable content without spending too much time or effort. If your community is the victim of a spam attack, or perhaps even just an over-enthusiastic poster, you want to be able to hide, lock, move, merge and delete content quickly. Throughout the entire suite, whenever you content (be that topics in IP.Board, files in IP.Downloads or even comments on a particular file in IP.Downloads or anything else you can think of), as a moderator, when you move your mouse over it, you will see a checkbox, and at the top of the list, you have controls to quickly select particular items: As you can see, in addition to checking individual items or all items, quick options are available for me to select all hidden, unapproved, pinned, locked or featured items, or even the items that I personally have read or not read. After selecting one or more items, you will see a menu appear at the bottom: This menu is incredibly smart. It automatically shows you options available based on the type of item you're looking at and the specific items you've selected. For example, here in IP.Downloads I see the options (from left-to-right): feature, pin, hide, lock move and delete (if you hover over any of the buttons a tooltip will show you what it is). If, I'm in IP.Board instead, I see a slightly different bar: Here, I have two new options: merge and Saved Actions (the new name for the IP.Board "Multimod" feature which allows you to define specific actions to do multiple moderator actions quickly). Also, it takes into consideration the specific items I've selected - if I select items which are not currently hidden, there is the "hide" button - if I select items which are currently hidden, there is the "unhide" button - and if I select a mix of both, I see both buttons. After clicking a button, the action is performed on all items and I'm taken back to the screen. Here's a short video demonstration of this in action: Quick editing Editing posts and comments is something moderators do on a daily basis. We already have quick reply (where when making a post or comment, it appears using AJAX without a page reload) and now in 4.0, we have quick edit too. When you click edit, the post/comment immediately changes into an editor: And when you click save, the editor disappears and is replaced by the new content. Here's a short video demonstration of this in action:
-
4.0 - Moderation Part 3: Reports
Effective moderation features are essential for online communities. Forums, blog entries and member-to-member messaging are particularly attractive for spam bots and nuisance users alike. IPS Social Suite has always been best in class when it comes to moderation features with features like the free IPS Spam Service that are completely unmatched by other web applications. Over this series of 5 blog entries I'm going to introduce you to some of the new moderation features in the IPS Community Suite 4.0. Part 1: Setting up moderators Part 2: Approval Queue Part 3: Reports Part 4: Effective Moderation Part 5: Warnings Back in IP.Board 3.0, we introduced a feature which at the time we called the "Report Center". Before this, if a user clicked the "Report" button, it would send a personal message to all the moderators for the forum the post was in (seriously). The Report Center was one of my favourite features in IP.Board 3.0 - it provided a great way for moderators to collaborate on reports and know the action that was taken. For 4.0 - we wanted to make this even more useful. We had 2 goals:It should be easy to set up and use. It currently has lots of configuration options dotted around the Admin CP and can feel a little confusing ("statuses" have "points" which leads to different coloured "flags" on reports) - it should be much easier for moderators to see what's important. When viewing the report itself, moderators should be able to see all the information they need immediately, and take action, without leaving the screen, making it quick and painless to deal with reports. The first part was making it easy for users to submit reports (if submitting a report is difficult or time-consuming, users won't do it, which defeats the point of having the feature). We've made it so when clicking the "Report offensive content" button next to posts, comments, messages, etc. a modal window will pop up - here the user can optionally fill in a reason for their submitting the report, and when submitting, the modal window just disappears, with no page reload, so the user is not interrupted from what they're doing. Video Demonstration Next we wanted to improve how moderators deal with reports - here's a screenshot of the report screen: Right from this page I can:See the content that was reported - I don't have to click anywhere to view it (naturally, I can click on the title to be taken to the actual content if I want to see it in context). Edit or delete the content. If I do this, it will do it via AJAX, without me ever leaving the page. Video Demonstration See any warnings that have been given in the past to the user who posted the content being reported, and issue them with a warning (which will be issued without me leaving the page). Flag the member as a spammer, which will automatically take all the appropriate action for that, depending on how I've set it up in the Admin CP. See who has reported this content, and the message they provided with the report. By hovering on their photo I will see their hover card which allows me to send them a message (which will be sent without me leaving the page). See any comments on the report from other moderators and make a comment on the report - comments are submitted by AJAX so I can make a comment quickly. Change the status of or delete a report. Move to the next/previous reports pending.
-
Moderation Part 2: Approval Queue
Effective moderation features are essential for online communities. Forums, blog entries and member-to-member messaging are particularly attractive for spam bots and nuisance users alike. IPS Social Suite has always been best in class when it comes to moderation features with features like the free IPS Spam Service that are completely unmatched by other web applications. Over this series of 5 blog entries I'm going to introduce you to some of the new moderation features in the IPS Community Suite 4.0. Part 1: Setting up moderators Part 2: Approval Queue Part 3: Reports Part 4: Effective Moderation Part 5: Warnings Sometimes content needs to be approved before it can be viewed. This can happen when:Approval is enabled for a particular member (perhaps for a particular time after giving a warning) Approval is enabled for a group (perhaps for new members until they have been registered for a certain number of days) Approval is enabled for a forum/category/etc. Currently, if there is content requiring approval, badges display next to the forum/topic to alert moderators. While this works well it has some drawbacks: it means clicking around the community to find content, and if there's an area of your community you don't visit very often (personally I don't often check the gallery here) sometimes you might not notice something needs to be approved. For 4.0, we wanted to improve this. There were two main goals we set: What we've created is a new area of the moderator control panel which we call the Approval Queue. When you visit the approval queue, you see the first topic/post/comment/whatever which is pending approval: As you can see, the page shows you clearly who posted it, what it is and the content. You can click on the badge on the right (in the screenshot above where it says "File Comment") to be taken directly to it if you want to see it in context. At the top, you can see 3 really clear actions: approve, skip and delete. Clicking any of these will do that action, and then immediately show you the next thing pending approval. This allows moderators to move through the queue really quickly and effortlessly. By clicking on the author's name, you can also issue a warning, flag the user as a spammer and send the user a message - all this is done without leaving the page: And when all content has been approved, you can enjoy the satisfaction of an empty queue: Here's a video of it in action: As an incidental feature - previously if a member made a post and it needed to be approved, they would get a confirmation message telling them so but wouldn't be able to see the post. This sometimes led to confusion when members missed the confirmation message and thought their post hadn't been submitted. In 4.0, users can now see their own posts which are pending approval: [*]Content from across the suite should be pulled into a single area for moderators so moderators can locate content pending approval manually. [*]Moderators should be able to act on content pending approval (usually by approving or deleting) quickly.
-
4.0 - Moderation Part 1: Setting up moderators
Effective moderation features are essential for online communities. Forums, blog entries and member-to-member messaging are particularly attractive for spam bots and nuisance users alike. IPS Social Suite has always been best in class when it comes to moderation features with features like the free IPS Spam Service that are completely unmatched by other web applications. Over this series of 5 blog entries I'm going to introduce you to some of the new moderation features in the IPS Community Suite 4.0. Part 1: Setting up moderators Part 2: Approval Queue (New Feature) Part 3: Reports Part 4: Effective Moderation Part 5: Warnings Up until now, each application has been responsible for managing it's own moderator permissions (for example, you go and set up a moderator in the forums app, then in the gallery app, etc.) and there's been a concept of "global" or "super" moderators who can perform all moderator actions in all applications. In IPS Community Suite 4.0, we're centralising the creation and assigning of moderator permissions, and are doing this separate from groups (so you can now make just a member a moderator without putting them in a special "moderator" group). It works very similar to Admin Restrictions in 3.x. Here is the Moderators page: (In this screenshot I've given moderator controls to everyone in the groups Administrators or Moderators, and to the user "Brandon") When editing a moderator you see all of the permissions available across all applications. This screenshot shows global moderator permissions which apply across all applications: If you do not want to allow any of these globally, you can make them available only to certain areas - when any option is toggled off, the equivalent option will show under each application tab, along with an option to select which areas of that application it can be done in. For example, if I disable the "Can edit all content?" option, a "Downloads" tab appears with the following options: This allows me to choose what the moderator can edit, and in which categories they can do it. A similar tab appears for each application I have installed, or additional options appear on the tabs. Also when editing a moderator I can control permissions not related to content, for example, how they can use the warning system: Member management permissions: And more. When editing a moderator, I also have the option to "Give All Permissions" which makes them akin to "global" or "super" moderators in 3.x. When editing a member which has been given all permissions, I will see a message reminding me that if I remove any permissions they will no longer be a global moderator:
-
4.0 - Nodes & Content Items
Reminder: this blog covers the technical details of 4.0's programming. For details on 4.0's features, follow our main blog. Introduction For almost all applications in the IPS Social Suite (IP.Chat being the notable exception), there are three components: Each of these different types of items share many common features. For example, in all applications you can "follow" nodes and Content Items, you can like (or give reputation on) Content Items and comments. There's also searching, tagging, moderator controls (pinning, locking, etc.), sharing, reports and so on. Up until now, applications were largely in charge of managing these different components and their relationships themselves, and utilised often complicated extensions to implement the common features. In 4.0, these components are handled differently. Each component follows an , extending a central class for the component, and implementing interfaces to enable additional features. Working with objects So, taking IP.Board as an example, the classes for each of the components (forums, topics and posts) will start off like this: [*]Categories created by the administrator. For example, forums in IP.Board, categories in IP.Downloads, calendars in IP.Calendar). In 4.0, the terminology used throughout the code for these is "Nodes". [*]Content created by users, usually (though, not always) within categories. For example, topics in IP.Board, files in IP.Downloads, events in IP.Calendar, images in IP.Gallery, personal conversations). In 4.0, the terminology used throughout the code for these is "Content Items". [*]Comments posted on Content Items by other users. In most applications these are simply called "comments" though in IP.Board they are called "posts" and in IP.Nexus and IP.Downloads they take the form of reviews. Active Record design pattern namespace IPSforums; class Forum extends IPSNodeModel { ... } class Topic extends IPSContentItem { ... } class Post extends IPSContentComment { ... } In , I already talked about how Nodes work and showed how easy it is to start using them. Content Items and comments are the same, with very little additional programming (only specifying a few properties to specify what database table to use and the names of the other classes they relate to), we can start using them. For example, to get a topic from the database, I just do: an earlier blog entry $topic = IPSforumsTopic::load( 1 ); In this example, 1 is the ID number. If I was accepting user input, I could just wrap it in a try/catch statement. I could also, rather than using load() use an alternative factory method, loadAndCheckPerms(), which automatically checks if the currently logged in user has permission to view and throws an exception if not: try { $topic = IPSforumsTopic::loadAndCheckPerms( IPSRequest::i()->id ); } catch ( IPSContentNoPermissionException $e ) { IPSOutput::i()->error( "You do not have permission to view that topic.", 1, 403 ); } catch ( OutOfRangeException $e ) { IPSOutput::i()->error( "Could not find topic. It may have been deleted.", 2, 404 ); } In the object, properties match the columns from the database table. For example, to set the page title to the topic title, I just do: IPSOutput::i()->title = $topic->title; There's also lots of methods available. For example, to get the IPSforumsForum object of the forum the topic belongs to, I just do: $forum = $topic->container(); Or to get the IPSMember object of the member that posted the topic, I just do: $author = $topic->author(); An Example: Getting the latest 5 topics One thing which is particularly easier now is that now the central classes handle common functionality, you can easily obtain data without having to worry about if everything has been accommodated - the class handles it automatically. I already showed how loadAndCheckPerms() works - for a more complicated example, let's say you wanted to get the 5 most recent topics to display in the sidebar. Previously you'd have to do a query, joining on the permissions table, providing the permission mask IDs of the current user manually, remembering to check to exclude hidden topics (unless of course, the user had permission to view hidden topics). In 3.x, it would have looked something like this: $member = ipsRegistry::instance()->member()->fetchMemberData(); $topics = ipsRegistry::DB()->buildAndFetchAll( array( 'select' => '*', 'from' => array( 'topics' => 't' ), 'where' => ipsRegistry::getClass('class_public_permissions')->buildPermQuery( 'p', 'perm_2' ) . ( !$member['g_is_supmod'] ? ' AND queued=0' : '' ), 'add_join' => array( array( 'select' => 'p.*', 'from' => array( 'permission_index' => 'p' ), 'where' => 'p.perm_app="forums" AND p.perm_type="forum" AND p.perm_type_id=t.forum_id', 'type' => 'left', ) ) ) ); In 4.0, the same thing can be done with just one line of code: $topics = IPSforumsTopic::getItemsWithPermission( NULL, 'start_date DESC', 5 ); Naturally, one could have written a method to do this in 3.x, but in 4.0, because it is handled centrally, it is common to all applications. If a new feature is added which affects the functionality (such as when hiding content was added), each application does not have to be updated. Adding Features I already mentioned how there are certain features, like tagging, reputation, searching, etc. which are common to Nodes and Content Items throughout all applications. In 3.x, integrating these features involved writing a usually lengthy, extension. In 4.x, implementing most of these features is as simple as adding a few elements to your class. For example, let's take tagging. In 3.x, we have lengthy . It involves creating an extension, which in the IP.Board application totals 360 lines of code. In 4.x, you simply add an interface to your class - changing this: developer documentation for implementing tagging class Topic extends IPSContentItem { ... } Into this: class Topic extends IPSContentItem implements IPSContentTags { ... } That's all there is to it. Having done that, the form where a user adds or edits a topic will immediately gain a tags input field (the elements included on the form is handled centrally) and I can now call an additional method to get the tags on any topic so that I can display them in the HTML: $tags = $topic->tags(); Here is a screenshot of the full developer documentation for tagging in 4.x: The programming method employed here is actually more suited to traits, as implementing the interface does not involve adding any additional code to your class. The reason we've chosen to do it this way though is because traits are only a feature in PHP 5.4 and above, and we wanted to support PHP 5.3. It is likely that in a future version of IPS Social Suite we will switch to using traits. Other examples Reporting In 3.x: - 502 lines for IP.Board. In 4.0: Read Markers (shows if content has been read or not) In 3.x: - 146 lines for IP.Board, plus manually marking items as read. In 4.0: Liking / Reputation In 3.x: - 222 lines for IP.Board. In 4.0: Following In 3.x: - 357 lines for forums, plus 361 lines for topics in IP.Board. In 4.0: For content items: For comments: http://www.invisionpower.com/support/guides/_/advanced-and-developers/application/application-extension-reportplugins-r100 http://www.invisionpower.com/support/guides/_/advanced-and-developers/application/item-marking-r211 http://www.invisionpower.com/support/guides/_/advanced-and-developers/application/application-extension-reputationphp-r101 http://www.invisionpower.com/support/guides/_/advanced-and-developers/application/application-extension-like-r69
-
4.0 - File Storage
Introduction The IPS Social Suite needs to store lots of different files - there's attachments and profile photos uploaded by members, CSS and JavaScript files, emoticons, etc. In IP.Board 3.x, various images got stored in different places: Files uploaded by users get put in the /uploads directory. If you have a complicated setup, it's difficult to handle these. If you have a load-balanced cluster you need to set up an environment whereby all files are stored on a single server, or all uploaded files are synched between servers, but serving these files over a high-performance CDN can be difficult. CSS, JavaScript files, images and emoticons get put in /style_* directories. If you want to serve these over a CDN, you can do so, but you need to copy the files over yourself. Other pieces of data are written to disk as a caching mechanism. This has the same issue with load-balanced environments as file uploads. Some applications had other methods - for example, IP.Downloads allows you to store files on a remote server using FTP. In 4.0, we wanted to pull this all together and build a much better system for storing files and build the whole system with high-performance environments in mind. File Storage In 4.0, you have several different ways to store files:On a local server On a remote server using FTP (which you can use to upload files to many CDN services) As binary data in the database On Amazon S3 You can set up different configurations and choose which configuration to use for different types of files. For example, if you want to store user's profile photos on Amazon S3, but you want attachments to be on the local server, or even a different Amazon S3 bucket - 4.0 can handle that. And if at any point you change your mind about which storage method you want to use, the system will automatically handle moving all the files for you. Everywhere that writes a file will use this central system - so IP.Downloads and IP.Gallery are included too. Caching There are lots of places throughout the suite where the same stuff needs to be retrieved or calculated over and over - for example, certain configuration settings, language data, information about the installed applications, etc. If this data can be cached, not only does it alleviate database load, it means the PHP code doesn't need to re-process the data. In IP.Board 3.x, some of this was stored in a particular database table and could be cached using a proper caching system - but it was difficult to configure, and not everything used it - compiled HTML templates, language strings and more were saved as files in the /cache directory, which causes difficulties for load-balanced cluster environments. In 4.0, we've overhauled all of this. For things that need cold storage (like compiled HTML templates) - you can choose either the file system or the database for storage. The data can then cached, along with anything else which might benefit from caching (like settings, application data, etc.) using one of 5 supported caching methods:APC eAccelerator Memcached Wincache XCache
-
IPS 4.0: Plugins
Introduction Modifications, add-ons, plugins, hooks - whatever your preferred name for them is - 3rd party code modifications are an important part of any successful web application. It wasn't that long ago that the way you did this was manually opening up files and copying and pasting bits of code in, or the really cool web applications had points scattered throughout the code for modifications to be injected into, or even scripts which opened up the files and made the changes for you (I'm not joking, that's seriously what used to go on!). In fact, IP.Board was one of the first web applications to, using OOP, support modifications in a more structured way. Currently, we largely have 2 types of modifications: applications, which add whole new areas and functionality to your site (all of our applications: IP.Blog, IP.Gallery, IP.Downloads, IP.Chat, IP.Content and IP.Nexus use this architecture) and hooks which modify or extend the functionality of the IPS Social Suite or of applications. Applications themselves are sort of self-governing so there isn't much to say about them, with one exception: applications will now be able to be downloaded and subsequently installed into your Admin CP as one file - you will not have to FTP upload application source files. The file will just be a regular .tar file, so course, if you were so inclined, you could open it and go old skool. For the rest of this blog entry, I'm going to focus on hooks. Though parts of this blog entry will be more technical in nature than our others, I've tried to keep it just to what everyone will be interested in, and leave the boring stuff until the end. Terminology The term "hook" in 3.x is ambiguous. Sometimes it refers to the whole thing (e.g. "install a hook") and sometimes it refers to a specific technical part of that - the code which overloads other code (e.g. "skin hook", "library hook"), which are, even more confusingly, sometimes called "hook files". In 4.0, we've decided to rename hooks to plugins. The technical parts which make up a plugin will still be referred to as hooks. Sandboxing Plugins, by their nature, extend functionality already present on your site. Up until now, if a plugin experiences a problem (for example, if a new version is installed which the plugin doesn't support) it can cause an error on your site, which disabling the plugin fixes. Starting in 4.0, plugins will be sandboxed. This means that if a plugin experiences an unexpected error (such as a database driver error), your site will automatically fallback to the default behaviour, and your users will never know anything went wrong. Simple (yet advanced) settings In IP.Board 3.x, the Admin CP maintained a massive central area for managing most (though not all) settings. Plugins could add settings to this area, though there was no real standard to where to do that. Also, because this area was separate from the area where you install plugins, it could sometimes be confusing how to configure a plugin after installing it. In 4.0, each plugin is allocated a settings page which is accessed just by hitting the "Edit" button on the list of plugins. Plugin authors can manage this page how they like - rather than being confined to the strictly tabular layout and specific input types in 3.x. Versioning In 3.x, unlike with applications, there was no particularly clear way to upgrade a plugin from one version to another. In 4.x, plugins now support full versioning, so you can just upload a new version, and an upgrader will take care of it. Hook Types In 3.x, there were several different underlying types of hooks: Action overloaders - which allowed overloading the PHP class for any controller. Library hooks - which allowed overloading the PHP class for some (though not all) other classes. Data hooks - which allowed the modification of variables at specific, defined places in the code. Skin overloaders - which allowed overloading the compiled PHP class representing a group of templates. Template hooks - which allowed content to be inserted at specific points in templates. For 4.0, we've made some quite radical changes: Code Hooks The first 3 have been merged into one concept we call "Code Hooks". Code Hooks can overload any class (even things which presently can't be overloaded like extensions) through a technique called monkey-patching (more details have been mentioned in the developer channel). This, combined with the use of Active Record models for all content items (so "Topic", etc. is a class that can be overloaded) also makes data hooks obsolete. Theme Hooks The last 2 have also been merged into a concept called "Theme Hooks" (we're also renaming "skin" to "theme"). The way the current template hooks work is to insert content around certain pre-defined tags in the template. The problem is, not always is the point the plugin author needs available, also this is done in a way the content being inserted isn't aware of it's surroundings, which makes it difficult for things like adding a button to every post, which would need to know information about that post. After thinking for ages about a better way to facilitate theme hooks (I was halfway through a system which injected hook points automatically at compile time), our designer Rikki reminded us that a pretty well-known method for selecting HTML elements already exists... CSS selectors. Video demonstration What's really cool about this is that the content used acts as if it was part of the template - if for example, it's inserted in a foreach loop, the variables created by that are available. It can also use template logic and everything else templates themselves can do. On the back-end, these are compiled into a file which behaves like a 3.x skin overloader - so if it is necessary (or just desired) to overload the compiled version of the template, that is still possible. Theme hooks work for the Admin CP as well as the front-end. Developer information Developers no doubt would like to know the technical information of how this all works. Rather than write a blog entry covering all the different parts of plugins, we thought you might be interested to just see the developer documentation. We have 2 articles we can show you - one covering all the technical details of plugins, and another which provides a step-by-step guide for how to create a plugin.
-
IPS 4.0: Internationalization and Localization
One of the things we wanted to focus on for IPS Social Suite 4.0 right from the beginning was providing better support for sites which do not use English or use multiple languages (or, as it was scribbled on my whiteboard, "++ i18n/L19n"). In this blog entry I'm going to cover some of those changes and new features. Translatable Everything Currently when you create a forum, user group, custom profile field, etc. you have to give it a title and can only do this in one language. If you have more that one language installed, you might want to provide different titles for different languages. In 4.0 you can do exactly that - if you have only one language installed, these fields will continue to show as normal text boxes - however, if you have more than one installed you'll see several text boxes like this: Visual Language Editor One feature that has been really popular in IP.Board is the Visual Skin Editor - a tool which allows you to browse your site, and click on elements to bring up a colour selector to change it. What if we could take this idea and apply it to translating as well? Allowing you to click on any word or phrase on your site and translate it there immediately. In 4.0, you can. Easier Language Management In addition to the visual translation we've also made several improvements to the traditional translation method: As you search for a language string, results appear as you type. Editing a language string saves immediately without needing to click a save button. Filter tabs can show you words/phrases which have not yet been translated or the translation is out of date (meaning we've changed the default English value for the word/phrase since it was translated). We've also made importing/exporting much faster and more reliable - no matter how large your language is (it will grow as you add more applications of course) there is now no risk of hitting an error importing/exporting (for those interested in the technical side of how this is achieved, see this blog entry). An exported language pack will also now maintain information on the version of each application it was exported from, so that the filter which shows outdated language strings is always accurate. Automatic Language Detection Let's say you have Spanish and French languages installed on your site - up until now, you'd have to choose one default language, and users who want the other would have to manually choose it (which can be extremely difficult to find how to do when you're browsing a site in a foreign language). In 4.0, we automatically examine the information that the user's browser sends (which includes their preferred language) to choose the best one out of what's available, if that user hasn't already set an explicit preference. Pluralisation In English, pluralisation is very simple - for most nouns, you just append "s" on the end, with some variation for certain words. This however, isn't the case in all languages - for example, I was speaking with the owner of a site in Slovak recently who was telling me that the word "records" changes depending on the number of records there are - for 2 records, it's "2 články", but for 5 records it's "5 článkov". Currently, most language strings only have a singular and plural form (as is all that's needed in English) - meaning having the site show "2 články"/"5 článkov" was impossible. In 4.0, we've introduced some really basic logic into language strings to accommodate this. Rather than having, for example, two language strings with the singular and the plural, there is now one with a value like this: {# [1:record][?:records]} The # indicates where the number will go, then each set of square brackets represents a possible value - the number before the : indicating the number which will cause that to show, and ? meaning "all other numbers". So for our Slovak example, we'd set the value to: {# [1:článok][5:článkov][?:články]} On display, it will automatically show the appropriate version. Lists Along a similar thread to pluralisation, we've also made the way lists are formatted to be customised through a special language string. For example, a list in English looks like "one, two and three". However, in Japanese, it's "一、二、三。" (the comma symbol is different and there's no "and") - similarly Arabic, Thai and others have similar differences. In 4.0, simply by changing an example language string, this can be changed. In the default language, this language string is: a, b and c For our Japanese example, we'd just change it to: a、b、c UTF-8 Without wanting to get into too much technical detail - UTF-8 is the most common of many ways text can be encoded for storage and display on webpages. UTF-8 has been the default encoding in our software since IP.Board 3.0. Some sites which have been around for a long while though may not be using UTF-8. This can cause issues with some features where UTF-8 encoding is expected (for example, many features which rely on JavaScript require UTF-8 due to JSON only supporting it and nothing else). In addition, some sites may try to use UTF-8, but content is actually stored differently as the database is set to a different encoding, which can also cause issues. In 4.0, we're going all UTF-8. If you're not already on it, the upgrader will convert data. This means a much more reliable and compatible way of handling text.
-
4.0 - Rethinking XML Handling
The IPS Social Suite stores skin and language (and some other stuff) in xml files which are imported into the database at installation and upgrade. The reason we do it this way is so of course, you can export skins and languages and install them on other sites or distribute them via the IPS Marketplace. I'm not the biggest fan of PHP's XML handling at the best of times (it would seem whoever wrote the SimpleXML class and I would disagree on the definition of "simple") and had already changed some of the places we use XML to use JSON instead, but these skins and languages are particularly difficult because they can get huge. Handling these large files, especially when combined with sub-par servers can lead to memory exhaustion or maximum execution time timeouts. Our current method was taking both too much memory, and too much time in a single HTTP request. So we had to come up with something better. At first we considered splitting the XML file into several, but that would mean either requiring people installing a new skin/language to upload multiple files (which we deemed not acceptable) or compressing them in some way (which is another of PHP's weaknesses, and would have just created another problem). We also researched different markup languages, however found similar problems with everything. We also had to make sure that any solution didn't step on the toes of any of our other 4.0 goals, in particular we want to completely eliminate writing cache files to disk so as to better support cluster environments. The solution was two-fold. To resolve the memory problem, we decided to use the XMLReader and XMLWriter classes - these are non-cached, forward-only classes for reading and writing XML. Rather than store the document in memory, you can only read/write one node at a time, and can only move forward, not backwards. Even with this approach though, we needed to account for the fact that importing is an intensive operation anyway, and one that needs to be staggered. To accommodate this, we wrote a simple AJAX-based "redirector", which continuously fires HTTP requests at a PHP controller until the controller reports the import is finished (it displays a fancy progress bar to the user while this is happening). We decided to make the AJAX redirector a helper class so that it can be used elsewhere and by third-party developers (rather than our current approach in some areas of making the user sit through loads of physical redirects). The code is really simple: IPSOutput::i()->output = new IPSHelpersMultipleRedirect( /* Query string which will take us back to this controller */ 'app=foo&module=bar&controller=baz&do=process', /* Code to run for each HTTP request */ function( $data ) { // If we're not done yet... return array( $data, // Data to get passed back to this function, "Processing...", // Message to show (via AJAX) to the user 50, // [Optional] Number between 1 and 100 to indicate progess for progress bar ); // If we're done return NULL; }, /* Code to run when we're done */ function() { // Code that runs when we're done } );