Closed (fixed)
Project:
Openlayers
Version:
6.x-2.x-dev
Component:
Code
Priority:
Normal
Category:
Task
Assigned:
Unassigned
Reporter:
Created:
28 Apr 2010 at 13:02 UTC
Updated:
23 Jun 2010 at 13:00 UTC
Jump to comment: Most recent file
Working through some strict issues, I noticed that one can render a map that does not have values that are assumed through the rendering process.
For instance, layers, styles, width, height.
Given the testing results, somewhere along the line, CCK is trying to render a map that has no values
(which is not good for CCK), but we also need to ensure that this won't get processed.
I would suggest a simple function to go through the map array to fix or throw any errors. I suppose there is some discussion on what should stop a map from being rendered.
| Comment | File | Size | Author |
|---|---|---|---|
| #10 | map-structure-handling-784092-10.patch | 3.76 KB | zzolo |
| #9 | cleanup_openlayers.patch | 8.56 KB | tmcw |
Comments
Comment #1
tmcw commentedI would kind of go the opposite direction of more automation in making map arrays. I think that the code should basically require its implementors - openlayers_ui, openlayers_cck, other modules - to follow a much stricter set of requirements. It just doesn't do us any good to have a map array that could have so many different forms. Even if openlayers.js there's a switch for some random 'other form' of map options that I don't know where it comes from. So, less complexity, more strictness is my motto here.
Comment #2
zzolo commentedI am cool with that. My point is just to ensure that we do checking and either fill in empty/bad values or throw errors. We can't ever assume what data is coming into our public API functions.
Comment #3
tmcw commentedI feel like we should make assumptions about what data is coming into our public API functions. Filling in empty/bad values just makes it harder to develop stuff for this module and makes future compatible much harder because people are throwing a variety of stuff at these functions. They are APIs, therefore there are restrictions with how they are used. It isn't a condition of an API that it never throws errors, or puts up with bad implementors.
Comment #4
zzolo commentedWe can never make assumptions about what data comes into public API functions. This is programming 101. http://api.drupal.org/api/function/node_load
Right now, someone could easy do this:
openlayers_build_map(123);and the function still makes the assumption that that data is an array, let alone that there are specific parts in that array.But, that does not mean that we have to support bad data. I am fine with throwing errors if values are not provided. But we currently don't have robust checking on data coming into the map render function and therefore bad data gets put through the rendering process. We do have an error checking at the end of the rendering process, but that is for higher level and post-render errors.
Comment #5
tmcw commentedMust've missed Programming 101 in undergrad CS :)
No, they cannot. Try it yourself.
Another no. If the function assumes that a type is an array, and it calls an index (see example above), then PHP will report that you're 'doing it wrong.' It is never a good idea to implement some sort of weird strong-typing type-checking system in PHP when PHP has its own, and it is an even worse idea to do this so that people who are implementing things using this module (developers) do not need to know its API. The API is documented, and comments reveal correct values and their types. If you do it wrong, then you get the same result as when you call any other function in PHP with the wrong kind of argument - a PHP error, not a Drupal error.
Apparently this is turning into another big ol' argument, so I'll just put it on the backburner for now and focus on other things. Not sure what your point really is or how node_load supports it.
Comment #6
zzolo commentedHere is the output of
openlayers_build_map(123);Yes, PHP does tell the system as a warning and only if specific users have these warnings displayed. Once data comes into an API function we are responsible as to what happens and specifically what gets displayed on the screen or sent to logs. We need some simple data checking and meaningful error messages. This could mean returning it via the function, like what we are doing, or actually raising errors. These errors are not valuable, and we are allowing bad values to proliferate through the render process.
As far as the relevance of the node_load(). It actually handles the different data types appropriately that come into the function. And I would assume if you did something like
node_load(FALSE)you would get a return value FALSE and no PHP warnings. Returning FALSE is not that helpful, but we don't even have that.This is what I learned in high school programming and CS undergrad as well. I am sorry for the big argument and getting heated about it, but this seems really basic to me.
Comment #7
tmcw commentedSorry, but that error seems massively straightforward to me: it's telling you that you need to use an array.
node_load supports multiple types for its arguments and handles those types. That does not mean that it will eat anything and guarantee that everything will be just fine. Same goes for other functions that support multiple types. I think that somehow this is getting smeared into a really bad idea of making PHP strongly typed within this module (it ain't) or guaranteeing that the module should not throw type errors when people give it incorrect types. Perhaps you're confusing this system with C++ or making assumptions about the API that I am not; nevertheless, I sadly must admit that I am not going to change my opinion on this issue. Once again, it is absurd to implement strong typing in PHP, and it is equally absurd to replace PHP's type checking system with something inside this module. You might want to talk to drupal people about this, or look for more examples, but there's a serious misunderstanding there.
I could continue to argue about this, but I'm not going to. I'm going to write patches and apply them on this ticket. If you want to give examples, citations, etc., of your opinion, please do.
Comment #8
tmcw commentedAlso: if you're looking for strict typing, let's just do it, instead of faking it within the function body. However, this kills the nature of PHP - for instance, the following definition of openlayers_build_map says that the argument needs to be a array, but the body of the function only needs $map to act like an array.
Comment #9
tmcw commentedHere's a patch that starts this process. This identifies the main need for some of the Javascript oddness going on in openlayers.js, and narrows down behavior a bit. I think that the map['errors'] structure is a bad vestigial practice (we should use exceptions, and not tolerate errors), but that'll come later. I'd appreciate testing on this, because it is a rather sweeping fix.
Comment #10
zzolo commentedI think I am a little confused on what you were trying to do with this patch. I think cleaning up that JS code and the options is good, but my goal with this was to allow for the PHP API side to be a little better to deal with. Here is a patch to check out. The key parts:
* Map rendering now returns a map array if errors are found. This is very important in my mind. Before we were just throwing back the theme function. We should be telling the code that calls the render about what is happening (ie errors).
* Map checking now includes looking for height and width.
* There is a little more pre processing on what comes into the map building process. This basically just sets up the arrays that are need for processing. This ensures that processing can happen without a hitch and then error checking can be more meanigful.
Also, I have started doing some D7 stuff and it looks like there is a fair amount of use of type casting parameters in functions. Though I think this is a good thing, having tested it out here, I recieved a really unusual error if I put in a non-array into the rendering function.
Comment #11
tmcw commentedEr, I think we're moving in different directions here:
What I have are basically opinions, not divine commands, so I'll state them as such.
What my patch was aiming at is removing the if-else hooks that have accumulated through the months - the biggest and most pernicious one is the if-else in openlayers.js, which currently only serves to make the poorly-formed defaults preset work - its definition of projections is behind the times. I'd like to remove as much code of that sort as possible, so that there's a much better-defined idea of what exactly the module accepts and what it doesn't - this will make the internal code much more testable and stable.
Comment #12
zzolo commentedI definitely support your changes in JS. I do think we are going in two different directions here. :)
So, about the $map['errors'] array and handling errors. I agree, its not a very great way to notify errors. But, its important to note that "map errors" are not PHP errors. Also, Drupal does not really have an error handling system that I know about (besides watchdog). Overall, we are not really do that much in openlayers_error_check_map(), so do we even need it? If we do, we need some mechanism to tell the user/program of the API about what went wrong and, IMO, in a way that is not just triggering a PHP error so that the user/progam of the API can handle these errors in its own way.
On the flip side, my goal was to do just a little preprocessing (I don't care about the name) of the map array that comes in, just to make sure that it can go through the processing more easily and get to the higher level errors and avoid some of the basic PHP errors. But this is not really all that necessary if we document the structure of the map array better and what is required.
Finally, I am not sure about your comment about map array and what you mean? Do you mean defining what a map array is? Its the data we store in a preset and gets passed to openlayers_build_map().
Comment #13
tmcw commentedRelative to the whole processing thing: I've realized that my aversion is basically because these processing functions are identical in function and specificity to 'goto'. And the fact that now they're turning into pass-by-reference shacks means that they aren't even referentially transparent. It's just a really bad thing.
If a map array is what a preset contains, then it is a preset - or a preset, right?
And, yes, I think that documentation should be first here, not 'preventing PHP errors from cropping up.' Preventing these errors from cropping up in this way - by silently defaulting their values - is just creating more confusing errors -or even worse - success despite incorrect use of the API. This is nothing but a bad thing, because then the API may change, and has a bunch of users counting on it to be something that it isn't, so there's no easy upgrade path. Like, the problem that I'm addressing in the javascript if-else statement is that the OpenLayers CCK module was doing the wrong thing, but the module and its javascript was putting up with it.
Okay: exceptions.
Comment #14
davideads commentedThe whole structure of the rendering pipeline is confusing and hides important details and functionality far down in the stack. Those process functions really obscure things. IMO, while it may be necessary to process a map, passing in a structure that is called a map but that actually is an elaborate array that gets parsed and the ACTUAL data extracted and shoved back in. This is part of what I was grousing about in the issue I just created (http://drupal.org/node/805910). Shouldn't
openlayers_renderconsume "pre-built" map data directly and simply render it?Why should the rendering function care about presets or call a bunch of processing functions I don't expect it to? If I'm using OpenLayers as a developer, interacting with the OL module API, I should think the simplest approach is best: it should be up to me to create the appropriate data structure and provide data, and up to the module to render it...
Comment #15
tmcw commentedHi David,
Thanks for the input, but this ticket is about a different topic - let's keep discussion of a high-level rethink in the other ticket. I've responded to your points about render methods and why data isn't in the map array in the other ticket. That said, obviously I agree with the point that generic 'process' functions are a harmful addition to the module, and feel like that they should be entirely eliminated outside of hook-based usage.
Comment #16
zzolo commented@tmcw, I think your JS changes are good and should go ahead.
My time is limited and I don't think what I am trying to do is all that important at the moment. I do support something like this:
This is the direction of Drupal 7. My direction above was more ensuring types for the elements in that array as well, such as layers.
I think what is a good direction coming out of this is rethinking the error handling in the module as far as rending a map. This can go in another focused ticket.
I think @davideads makes a good point about how the rendering process happens. I think, we should expand the module to allow for layers and styles to be able to put directly in a map array. Once this happens, it makes sense to have better separation of the map building process and rendering process. But these things are for other tickets and discussions.
Closing for now.
Comment #17
tmcw commentedHuh? Why close this when it has a patch on it that you want to be committed?
... I'll reroll this ticket and commit it soon.
Comment #18
tmcw commentedFixed in http://drupal.org/cvs?commit=377664. This is a rather serious commit and we're dealing with backwards-compatibility problems in a few places, so marking as fixed and hoping for the best.